AngularJS multi screen validation on last step - angularjs

I have an angularJS application. I have implemented a generic workflow using $routeProvider, templateUrl & Controllers.
Each step(screen) is verified when user click on next button and moves to the next step if validation passes. If validation fails user is required to fix all the error, displayed on the screen, before moving to next step.
When user has visited all the screens(passed validation for each screen) all the breadcrumbs get enabled and now user can move freely between those steps/breadcrumbs.
Requirement:
Now I want to allow user to move freely between steps by clicking on the breadcrumbs and when user clicks on the lodge button, on the last step, validation for current as well as for all previous steps should be invoked, and clicking on the error user should be able taken to the relevant step/screen.
Also I want to keep the functionality of validating the individual steps on the click of next button.
As you can see each screen has a separate controller along with the scope.
Once user move from one step to another it can't access the previous scope.
Initially I thought of storing scope of each screen in an array, but once I move between steps new scope is created (as it should) and only current step has a form with valid data model and "valid" flag as false.
Form object at current step
Form object of other screen without and fields attached
I'm not very well versed with Angularjs and trying to get some idea weather
Is it possible what I'm trying to achieve keeping the existing functionality intact. (My understanding is that I can't have a single controller since I need to keep the functionality of validating each step individually)?
Is there a better way to trying to achieve this functionality?
PS: Sadly I can't upgrade to newer version of Angular.
Any help will be highly appreciated.
Form Validation
validator.validate = function($scope, submitCallback, additionalOptions) {
var options = {};
$.extend(options, commonOptions, additionalOptions);
var form = $scope[options.formName];
hideErrorMessages(options.errorContainerSelectorId);
if (form.$valid) {
submitCallback();
return;
}
showErrorMessages({message: composeAngularValidationErrors(form),
errorContainer: $('#' + options.errorContainerSelectorId)});
};
View:
<#assign temp=JspTaglibs["http://www.test.com/tags"]>
<div ng-controller="LodgeApplicationWorkflowController" ng-cloak>
<workflow-breadcrumbs></workflow-breadcrumbs>
{{model | json}}
<div ng-view>
</div>
<script type="text/ng-template" id="applicant-details">
<form name="form" method="post" action="#" class="standard">
<h3>Primary contact details</h3>
<div class="row">
<div class="span3">
<label for="owner-primary-contact">Primary contact:</label>
<select class="span3" id="owner-primary-contact" required name="applicantDetails.primaryContact"
ng-model="model.applicantDetails.primaryContactId"
ng-options="user.id as user.fullName for user in refData.contactInfos"
>
<option value=""></option>
</select>
</div>
<div class="span3">
<label for="owner-primary-contact-phone">Phone:</label>
<input type="text" class="span3" id="owner-primary-contact-phone" name="applicantDetails.primaryContactPhone"
readonly
ng-model="model.applicantDetails.primaryContactPhone"/>
</div>
<div class="span3">
<label for="owner-primary-contact-email">Email:</label>
<input type="text" class="span3" id="owner-primary-contact-email" name="applicantDetails.primaryContactEmail"
readonly
ng-model="model.applicantDetails.primaryContactEmail"/>
</div>
</div>
</form>
</script>
<script type="text/ng-template" id="lgc-methodology">
<form name="form" method="post" action="#" class="standard">
<h3>Describe the Your Methodology</h3>
<div class="row">
<div class="span9">
<label for="methodology">Describe the methodology which you propose to employ:
</label>
<textarea class="span9" id="methodology" name="methodology"
rows="10"
ng-maxlength="4000"
ng-model="model.methodology" required>
</textarea>
</div>
</div>
</form>
</script>
<script type="text/ng-template" id="approval-details">
<form name="form" method="post" action="#" class="standard">
<div class="row" ng-if="model.approvalDetails.planningApprovalsObtained === 'true'">
<div class="span9">
<label for="planning-approvals-details">Approval details:</label>
<textarea class="span6" id="planning-approvals-details"
name="approvalDetails.planningApprovalDetails"
ng-if="model.approvalDetails.planningApprovalsObtained === 'true'"
required ng-maxlength="4000"
ng-model="model.approvalDetails.planningApprovalDetails"></textarea>
</div>
</div>
<div class="row" ng-if="model.approvalDetails.planningApprovalsObtained === 'false'">
<div class="span9">
<label for="planning-approvals-details">Reasons:</label>
<textarea class="span6" id="planning-approvals-details"
name="approvalDetails.planningApprovalDetails"
ng-if="model.approvalDetails.planningApprovalsObtained === 'false'"
required ng-maxlength="4000"
ng-model="model.approvalDetails.planningApprovalDetails"></textarea>
</div>
</div>
<div >
<div class="row" >
<div class="span9">
<label for="environment-approval-details">Approval details:</label>
<textarea class="span6" id="environment-approval-details"
name="approvalDetails.environmentApprovalDetails"
ng-maxlength="4000"
ng-required="model.approvalDetails.environmentApprovalsObtained === 'true'"
ng-model="model.approvalDetails.environmentApprovalDetails"></textarea>
</div>
</div>
<div class="row" ng-if="model.approvalDetails.environmentApprovalsObtained === 'false'">
<div class="span9">
<label for="environment-approval-details">Reasons:</label>
<textarea class="span6" id="environment-approval-details"
name="approvalDetails.environmentApprovalDetails"
ng-maxlength="4000"
ng-required="model.approvalDetails.environmentApprovalsObtained === 'false'"
ng-model="model.approvalDetails.environmentApprovalDetails"></textarea>
</div>
</div>
</div>
</form>
</script>
<script type="text/ng-template" id="confirmation">
<form id="form" method="post" name="form" action="#" class="standard">
<div class="row">
<div class="span9">
<span class="checkbox inline">
<label for="confirm-information">
<input type="checkbox" id="confirm-information" name="confirmInformation"
ng-model="model.Confirmed" required />
I confirm that all the details are correct
</label>
</span>
</div>
</div>
</form>
</script>
<div class="form-actions">
<input type="button" class="btn" value="Cancel" ng-click="cancel()"/>
<div class="pull-right btn-toolbar">
<input id="previous" type="button" class="btn" value="Previous"
ng-click="workflow.handlePrevious()" ng-show="!workflow.isFirstStep()" ng-cloak/>
<input id="save-and-close" type="button" class="btn" value="Save draft and close"
ng-show="model.canSaveDraftAndClose && !workflow.isLastStep()"
ng-click="saveDraftAndClose()" ng-cloak/>
<input id="submit" type="button" class="btn btn-primary" value="{{workflow.getNextLabel()}}"
ng-disabled="!workflow.canNavigateToNextStep()"
ng-click="workflow.handleNext()" ng-cloak/>
</div>
</div>
</div>
Controllers:
angular.module('Test')
.config(function ($routeProvider) {
$routeProvider
.when('/applicant-details', {
templateUrl: 'applicant-details',
controller: 'ApplicantDetailsController'
})
.when('/methodology', {
templateUrl: 'methodology',
controller: 'MethodologyController'
})
.when('/approval-details', {
templateUrl: 'approval-details',
controller: 'ApprovalDetailsController'
})
.when('/confirmation', {
templateUrl: 'confirmation',
controller: 'ConfirmationController'
})
.otherwise({redirectTo: '/applicant-details'});
})
;
function LodgeApplicationWorkflowController( $scope, ctx, workflow, workflowModel, server, navigation) {
workflow.setSteps([
{
name: 'Applicant details',
path: 'applicant-details',
validationUrl: '/some url'
},
{
name: 'Methodology',
path: 'methodology'
},
{
name: 'Approval details',
path: 'approval-details'
},
{
name: 'Confirmation',
path: 'confirmation',
nextButtonLabel: 'Lodge',
onSubmit: function () {
disable('submit');
$scope.model.lodgeApplication = JSON.stringify($scope.model);
server.post({
url: ctx + '/some url' ,
json: JSON.stringify($scope.model),
successHandler: function () {
},
completeHandler: function () {
enable('submit');
},
validationErrorTitle: 'The request could not be completed because of the following issues:'
});
}
}
]);
function postInit() {
// To DO
}
function loadLodgement() {
// To DO
}
$scope.workflow = workflow;
$scope.model = workflowModel.model();
$scope.refData = workflowModel.refData();
$scope.accountDetails = {};
$scope.userDetails = {};
$scope.model.canSaveDraftAndClose = true;
server.getReferenceData([
'/URL1'
], function onAllReferenceDataRetrieved(data) {
$scope.$apply(function() {
$scope.refData.fuelSourceOptions = data[0];
$scope.refData.contactInfos = data[1].result;
$scope.refData.address = data[2];
$scope.refData.yearOptions = data[3];
$scope.refData.nmiNetworkOptions = data[4];
});
loadLodgement();
loadDraft();
});
$scope.saveDraftAndClose = function () {
var command = {};
server.post({
url: ctx + '/URL',
json: JSON.stringify(command),
successHandler: function (data) {
},
validationErrorTitle: 'The request could not be completed because of the following issues:'
});
};
$scope.cancel = function() {
navigation.to('Some URL');
};
}
function ApplicantDetailsController($scope, workflow, workflowModel, addressService, applicantServiceFactory) {
var applicantService = applicantServiceFactory();
if (!workflow.setCurrentScope($scope)) {
return;
}
$scope.model = workflowModel.model();
$scope.model.applicantDetails = _.extend({
owner: { address: {} },
operator: { address: {} }
}, $scope.model.applicantDetails);
addressService.initialiseAddress($scope.model.applicantDetails);
}
function MethodologyController($scope, workflow, workflowModel) {
if (!workflow.setCurrentScope($scope)) {
return;
}
$scope.model = workflowModel.model();
// Do something
}
function ApprovalDetailsController($scope, workflow, workflowModel) {
if (!workflow.setCurrentScope($scope)) {
return;
}
$scope.model = workflowModel.model();
$scope.model.approvalDetails = $scope.model.approvalDetails || {};
// Do something
}
function ConfirmationController($scope, workflow, workflowModel) {
if (!workflow.setCurrentScope($scope)) {
return;
}
$scope.model = workflowModel.model();
$scope.model.confirmation = { owner: {}, operator: {} };
$scope.model.confirmationConfirmed = false;
// Do something
}
WorkFlow
angular.module('Test')
.service('workflowModel', function() {
var refData = {};
var workflowModel = {};
return {
reset: function() {
workflowModel = {};
},
get : function(fragmentName) {
if (!workflowModel[fragmentName]) {
workflowModel[fragmentName] = {};
}
return workflowModel[fragmentName];
},
model : function(newWorkflowModel) {
if (newWorkflowModel) {
workflowModel = newWorkflowModel;
} else {
return workflowModel;
}
},
refData : function() {
return refData;
},
toJSON: function() {
return JSON.stringify(workflowModel);
}
};
})
.directive('workflowBreadcrumbs', function() {
return {
restrict: 'E',
template: '<ul class="breadcrumb">' +
'<li ng-class="{\'active\': workflow.currentStepPathIs(\'{{step.path}}\')}" ng-repeat="step in workflow.configuredSteps" ng-cloak>' +
'{{step.name}}<span ng-if="!workflow.visitedStep(step.path)">{{step.name}}</span><span class="divider" ng-if="!$last">/</span>' +
'</li>' +
'</ul>',
transclude: true
};
})
.factory('workflow', function ($rootScope, $location, server, validator, workflowModel, $timeout) {
function getStepByPath(configuredSteps, stepPath) {
return _.find(configuredSteps, function(step) { return step.path === stepPath; });
}
function validateServerSide(currentStep, callback) {
if (currentStep.validationUrl) {
server.post({
url: ctx + currentStep.validationUrl,
json : JSON.stringify(workflowModel.model()),
successHandler : function() {
$rootScope.$apply(function() {
callback();
});
}
});
} else {
callback();
}
}
function navigateNext(configuredSteps, currentStep) {
var currentStepIndex = _.indexOf(configuredSteps, currentStep);
navigateTo(configuredSteps[currentStepIndex + 1]);
}
function navigateTo(step) {
$location.path(step.path);
}
return {
setCurrentScope: function(scope) {
this.currentScope = scope;
this.firstStep = _.first(this.configuredSteps);
this.lastStep = _.last(this.configuredSteps);
this.currentStep = this.getCurrentStep();
if (!(this.currentStep === this.firstStep || this.hasEverVisitedSteps())) {
this.reset();
return false;
}
this.currentStep.visited = true;
hideErrorMessages();
this.focusOnFirstInputElementAndScrollToTop();
return true;
},
setSteps: function(steps) {
this.configuredSteps = steps;
},
focusOnFirstInputElementAndScrollToTop: function() {
$timeout(function() {
angular.element('select, input, textarea, button', '[ng-view]')
.filter(':visible')
.first()
.one('focus', scrollToTitle)
.focus();
scrollToTitle();
});
},
hasEverVisitedSteps: function() {
return _.find(this.configuredSteps, function(step) {
return step.visited;
}) !== undefined;
},
isFirstStep: function() {
return this.currentStep === this.firstStep;
},
isLastStep: function() {
return this.currentStep === this.lastStep;
},
currentStepPathIs: function(stepPath) {
return this.currentStep && stepPath === this.currentStep.path;
},
visitedStep: function(stepPath) {
return getStepByPath(this.configuredSteps, stepPath).visited;
},
getNextLabel: function() {
if (this.currentStep && this.currentStep.nextButtonLabel) {
return this.currentStep.nextButtonLabel;
}
return (this.isLastStep()) ? 'Submit' : 'Next';
},
handlePrevious: function() {
if (!this.isFirstStep()) {
var currentStepIndex = _.indexOf(this.configuredSteps, this.currentStep);
navigateTo(this.configuredSteps[currentStepIndex - 1]);
}
},
canNavigateToNextStep: function() {
return this.currentScope && (!this.currentScope.canSubmit || this.currentScope.canSubmit());
},
handleNext: function() {
var configuredSteps = this.configuredSteps;
var currentStep = this.currentStep;
if(this.isLastStep()) {
this.validateCurrentStep(this.currentStep.onSubmit);
} else {
this.validateCurrentStep(function() {
navigateNext(configuredSteps, currentStep);
});
}
},
validateCurrentStep: function(callback) {
var currentStep = this.currentStep;
if (this.currentScope.form) {
validator.validate(this.currentScope, function() {
validateServerSide(currentStep, callback);
});
} else {
validateServerSide(currentStep, callback);
}
},
getCurrentStep: function() {
return getStepByPath(this.configuredSteps, $location.path().substring(1));
},
reset: function() {
_.each(this.configuredSteps, function(step) { step.visited = false; });
this.firstStep.visited = true;
navigateTo(this.firstStep);
}
};
});

Related

Assign dynamic ng-model in a template for radio buttons

I use a directive to add images and radio buttons (per image). I also create dynamically ng-models. Now with my approach, the radio buttons will not be set. What's wrong? Thank your for your hints.
JS
.directive('oct', function() {
return {
restrict : 'E',
template : `
<div class="oImg" ng-repeat="image in images">
<a href="#" class="removeImage" ng-click="vm.removeImg(image)"
ng-show="isActive($index)"><i class="fa fa-trash"></i>
</a>
<img ng-src="{$image.src$}" class="images-item"
ng-show="isActive($index)"><span ng-show="isActive($index)" class="imgName">{$image.name$}</span>
<div class="sideSelect" ng-show="isActive($index)">
<div class="checkbox"><label>
<input type="radio" ng-model="eyeChanger[image.name]"
name="optionsEye"
ng-change="vm.changeEye(image, eyeChanger[image.name])"
value="RA">RA</label>
</div>
<div class="checkbox"><label>
<input type="radio" ng-model="eyeChanger[image.name]"
ng-change="vm.changeEye(image, eyeChanger[image.name])"
name="optionsEye" value="LA">LA</label>
</div>
</div>
</div>
`,
controller : ['$scope', '$http',
function($scope, $http) {
$scope._Index = 0;
// if current image is same as requested image
$scope.isActive = function(index) {
return $scope._Index === index;
};
// prev image
$scope.showPrev = function() {
if ($scope._Index != 0) {
$scope._Index = ($scope._Index > 0) ? --$scope._Index : $scope.images.length - 1;
}
};
// next image
$scope.showNext = function() {
if ($scope._Index < $scope.images.length - 1) {
$scope._Index = ($scope._Index < $scope.images.length - 1) ? ++$scope._Index : 0;
};
};
}]
};
})
vm.changeEye = function(img, value) {
$scope['eyeChanger'+img.name] = value;
...
Use:
vm.changeEye = function(img, value) {
̶$̶s̶c̶o̶p̶e̶[̶'̶e̶y̶e̶C̶h̶a̶n̶g̶e̶r̶'̶+̶i̶m̶g̶.̶n̶a̶m̶e̶]̶ ̶=̶ ̶v̶a̶l̶u̶e̶;̶
$scope.eyeChanger[img.name] = value;
...
There is no need to do this with ng-change as the ng-model directive does it automatically.
<div ng-repeat="image in images">
<img ng-src="{{image.src}}" />
<div class="checkbox"><label>
<input type="radio" ng-model="eyeChanger[image.name]"
name="optionsEye"
̶n̶g̶-̶c̶h̶a̶n̶g̶e̶=̶"̶v̶m̶.̶c̶h̶a̶n̶g̶e̶E̶y̶e̶(̶i̶m̶a̶g̶e̶,̶ ̶e̶y̶e̶C̶h̶a̶n̶g̶e̶r̶[̶i̶m̶a̶g̶e̶.̶n̶a̶m̶e̶]̶)̶"̶
value="RA">RA</label>
</div>
<div class="checkbox"><label>
<input type="radio" ng-model="eyeChanger[image.name]"
̶n̶g̶-̶c̶h̶a̶n̶g̶e̶=̶"̶v̶m̶.̶c̶h̶a̶n̶g̶e̶E̶y̶e̶(̶i̶m̶a̶g̶e̶,̶ ̶e̶y̶e̶C̶h̶a̶n̶g̶e̶r̶[̶i̶m̶a̶g̶e̶.̶n̶a̶m̶e̶]̶)̶"̶
name="optionsEye" value="LA">LA</label>
</div>
</div>
The radio buttons can be initialized:
$scope.images = [
{ name: "name1", src: "..." },
{ name: "name2", src: "..." },
// ...
];
$scope.eyeChanger = {
name1: "RA",
name2: "LA",
// ...
};

how can update my form in modal in angular js?

hello i am creating mean application in which i want to update record.the record is in table format and when user click on edit button then a modal appears with its database values on input text box . I have not any problem in updating field but i stuck in updating video part. How can I do it??
html form (i use single form for creating and updating)
<div class="panel panel-default">
<div class="panel-heading">Add Videos</div>
<div class="panel-body">
<div style="margin:10px;">
<form name="addVideos" class="" method="post">
<div class="alert alert-success" ng-show="success" style="background-color:black;">
<strong>successfully updated!!</strong> Redirecting to all videos page.
</div>
<div class="form-group">
<label>Title</label>
<input type="text" class="form-control" ng-model="form.title" required name="title" placeholder="Enter Title">
</div>
<div class="form-group">
<label>Description</label>
<textarea class="form-control" ng-model="form.description" required name="description" rows="5" id="comment" placeholder="Enter Description"></textarea>
</div>
<div class="form-group">
<label>Author</label>
<input type="text" class="form-control" required ng-model="form.author" name="author" id="exampleInputPassword1" placeholder="Enter Author Name">
</div>
<div class="form-group">
<label>duration</label>
<input type="text" class="form-control" required ng-model="form.duration" name="duration" id="exampleInputPassword1" placeholder="Enter Author Name">
</div>
<!-- <div class="form-group">
<label>ispublic</label>
<input type="text" class="form-control" required ng-model="form.public" name="public" id="exampleInputPassword1" placeholder="Enter Author Name">
</div> -->
<div class="form-group">
<label for="sel1">ispublic:</label>
<select class="form-control" ng-model="form.public" >
<option ng-selected="test==false" value="0">0</option>
<option ng-selected="test==true" value="1">1</option>
</select>
</div>
<div class="row">
<div class="col-md-2" style="margin-top: 19px;" >
<!-- <!ng-hide="display" !> -->
<input type="file" accept="video/*" file-model="myFile" required/>
</div>
<div class="col-md-8" style="margin-left:29px;">
<button ng-click="add == true ? uploadFile(form) : updateVideo()" class="btn btn-danger" ng-disabled="addVideos.$invalid" style="margin:10px;">Submit</button>
</div>
</div>
<progress value="{{progressBar}}" max="100" ng-show="view">
</progress>
<div class="progress" ng-show="view" style="width:40%;">
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="{{progressBar}}" aria-valuemin="0" aria-valuemax="100" style="width:{{progressBar}}%">
{{progressBar}}% Complete (success)
</div>
</div>
</form>
</div>
</div>
</div>
my controller
function generateUUID() {
var d = new Date().getTime();
var uuid = 'xxxxxxx.mp4'.replace(/[xy]/g, function(c) {
var r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
});
return uuid;
};
var localstorageApp = angular.module('BlurAdmin.pages.videos.allVideos');
localstorageApp.controller('TbleCtrl',['$rootScope','$scope', '$filter', 'editableOptions', 'editableThemes', '$window', '$http',
'$uibModal', 'baProgressModal','localStorageService','$state','$rootScope',
function ($rootScope,$scope, $filter, editableOptions, editableThemes, $window, $http, $uibModal,
baProgressModal,localStorageService,$state,$rootScope) {
var token = localStorageService.get('TOKEN')
if(token == null){
$window.location.href = '/index.html';
}
token = token.substring(1, token.length - 1);
$http.get("/api/loggedin/"+token).then(function(response) {
console.log("response"+JSON.stringify(response.data.error))
if(response.data.error == true){
localStorageService.remove('TOKEN')
$window.location.href = '/index.html';
}
});
$scope.users = [];
$scope.display=true;
// $scope.form = [];
//$scope.bool = null;
$scope.id = 0;
$scope.redirect = function () {
$window.location.href = "#/videos/addVideos";
}
$http.get("/api/all-videos").then(function(response) {
$scope.users = response.data.data;
console.log(response.data.data);
});
$scope.open = function(e,id,page, size, addOrEdit) {
$scope.updateVideo() = function(){
alert('working');
}
// $scope.bool = bool
$scope.id = id
$scope.display=true;
var modalInstance = $uibModal.open({
// animation: $ctrl.animationsEnabled,
// ariaLabelledBy: 'modal-title',
// ariaDescribedBy: 'modal-body',
templateUrl: page,
controller: 'ModalInstanceCtrl',
controllerAs: '$scope',
size: size,
// appendTo: parentElem,
resolve: {
users: function () {
return $scope.users;
},
id: function () {
return $scope.id;
}
}
});
modalInstance.result.then(function (selectedItem) {
// console.log("selectedItem"+JSON.stringify(selectedItem.data));
$scope.users = selectedItem;
// $scope.users.push(selectedItem.data)
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
$scope.removeVideo = function(id, $index) {
var m = parseInt(id);
if ($window.confirm("Are you sure you want to delete?") == true) {
$http.post("/api/delete-video/" + m).then(function(response) {
$scope.users.splice( $index, 1 );
});
// $window.location.reload()
} else {
}
}
$scope.openProgressDialog = baProgressModal.open;
// editableOptions.theme = 'bs3';
// editableThemes['bs3'].submitTpl = '<button type="submit" class="btn btn-primary btn-with-icon"><i class="ion-checkmark-round"></i></button>';
// editableThemes['bs3'].cancelTpl = '<button type="button" ng-click="$form.$cancel()" class="btn btn-default btn-with-icon"><i class="ion-close-round"></i></button>';
}
])
var qwe='';
angular.module('BlurAdmin.pages.users').directive('fileModel', ['$parse', function($parse) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
var model = $parse(attrs.fileModel);
var modelSetter = model.assign;
element.bind('change', function() {
scope.$apply(function() {
modelSetter(scope, element[0].files[0]);
qwe= element[0].files[0];
console.log(element[0].files[0].name);
});
});
}
};
}]).service('hexafy', ['$http', '$window','$timeout', function($http, $window,$timeout) {
this.myFunc = function (x) {
return x.toString(16);
}
// GET ALL INFORMATION IN VIDEOS
this.getAll = function(t,x){
console.log(x);
$http.get("/api/get-video/"+x).then(function(response) {
console.log(response);
// console.log(response.data.data);
console.log(response.data.response.data);
t.form = response.data.response.data;
// $scope.form.public = response.data.response.data.ispublic;
t.test = response.data.response.data.ispublic;
// console.log($scope.form.level);
// $scope.form.level = $scope.levels[response.data.response.data.level - 1];
// console.log($scope.form.level);
});
}
this.display = function(p){
console.log(p);
console.log(qwe);
}
this.updateVideo = function(){
console.log(qwe);
alert('working');
}
}]).controller('ModalInstanceCtrl', ['$scope', '$uibModalInstance', '$http', 'id', '$timeout','hexafy' ,function ($scope, $uibModalInstance,$http,id,$timeout,hexafy) {
$scope.form = {};
$scope.test = '';
// $scope.b = bool;
console.log($scope.b);
$scope.display=true;
console.log(hexafy.myFunc(187));
hexafy.getAll($scope,id);
console.log("id value "+id)
var file = $scope.myFile;
console.log(file);
}])
How could i detect file in modal??

How to check file type in kendo file upload using AngularJS?

I have kendo file upload with AngularJs which is working good for upload, Another requirement is Document Category is dropdown (Excel,Pdf,Word). Lets assume if user select excel from dropdown how can i restrict user to select only excel file by using onSelect method ?
So far tried code below...
main.html
<form name="addRiskForm" novalidate class="border-box-sizing">
<div class="modalForm">
<div class="row">
<div class="form-group col-md-12">
<label for="docCate" class="col-md-4">Document Category:</label>
<div class="col-md-8">
<select
kendo-drop-down-list
data-text-field="'text'"
data-value-field="'id'" name="attchCategory"
k-option-label="'Select'"
ng-model="attchCategory"
k-data-source="docCategoryOptions"
id="docCate">
</select>
</div>
</div>
</div>
<div class="row">
<div class="form-group col-md-12 fieldHeight">
<label for="issueNo" class="col-md-4">File name:</label>
<div class="col-md-6">
<input name="file"
type="file"
kendo-upload="fileAttachment"
k-upload="addMorePostParameters"
k-success="onSuccess"
k-error = "onError"
k-multiple="true"
k-options="fileAttachmentOptions"
k-select="onSelect"
/>
</div>
</div>
</div>
</div>
</form>
Ctrl.js
$scope.fileAttachmentOptions = assessmentDocConfig.fileAttachmentConfig;
$scope.docCategoryOptions = kendoCustomDataSource.getDropDownDataSource('RA_ATACH_TYP');
$scope.$on('addDocument', function (s,id){
$scope.riskAssessmentDTO.riskAssessmentKey = id;
$scope.viewDocumentWin.open().center();
});
$scope.addMorePostParameters = function (e) {
if (!$scope.attchCategory) {
e.preventDefault();
} else if (!$scope.attchDesc) {
e.preventDefault();
} else {
e.data = {
attchCategory:$scope.attchCategory,
attchDesc: $scope.attchDesc,
riskAssessmentKey: $stateParams.assessmentId,
};
}
};
$scope.onSuccess = function () {
$log.info('Upload Successfull...');
$scope.attchCategory = '';
$scope.attchDesc = '';
var filesToBeRemoved = $scope.fileAttachment.wrapper.find('.k-file');
$scope.fileAttachment._removeFileEntry(filesToBeRemoved);
console.log('Attachment Successfully Saved');
$scope.viewDocumentWin.close();
};
$scope.onSelect = function (e) {
$.each(e.file, function (index, value) {
var ok = value.extension == ".xlsx"
|| value.extension == ".pdf"
|| value.extension == ".doc"
|| value.extension == ".html";
if (value.extension === ok) {
e.preventDefault();
alert("Please upload jpg image files");
}
});
};
$scope.onError = function () {
$log.info('Upload Errored out...');
console.log('Error while uploading attachment');
};
config.js
fileAttachmentConfig: {
async: {
saveUrl: 'app/upload/uploadAttch',
removeUrl: 'remove',
removeVerb: 'DELETE',
autoUpload: false
},
template: '<span class=\'file-name-heading\'>Name:</span> <span>#=name#</span><button type=\'button\' class=\'k-upload-action\'></button>'
}
You could use the validation.allowedExtensions property, for example:
config.js
fileAttachmentConfig: {
async: {
saveUrl: 'app/upload/uploadAttch',
removeUrl: 'remove',
removeVerb: 'DELETE',
autoUpload: false
},
template: '<span class=\'file-name-heading\'>Name:</span> <span>#=name#</span><button type=\'button\' class=\'k-upload-action\'></button>',
validation: {
allowedExtensions: ["doc", "txt", "docx", "pdf", "jpg", "jpeg", "png", "xlsx", "xls"],
maxFileSize: 20000000, //20mb (in bytes)
}
}
In your specific example, you need to make this dynamic, so you should be able to adjust the values in the configuration object depending on what you've selected in the dropdown. So rather than referencing a static array, reference a variable that you can alter at runtime.
Further documentation:
https://docs.telerik.com/kendo-ui/api/javascript/ui/upload/configuration/validation#validation.allowedExtensions
https://demos.telerik.com/kendo-ui/upload/angular

ng-click ng-keypress passing form data not working

Im trying to send data from user input to display on the screen when button click.
The problem is that if i click on the button it simply passes to the next value without gathering the information and displaying in the screen. If i press ENTER it works how it should. i have searched all over internet several examples but simply couldnt get it to work. im using at the moment :
<button class="btn btn-lg btn-default next bt_submits" type="button" ng-click="addData(newData)">
<span class="bt_arrow"></span>
</button>
full html:
<div class="boxContent col-md-12">
<h1>{{lang.sec101.h1}}</h1>
<div class="col-md-12 lineBorder noPad" >
<div class="box1">
<p>
{{lang.sec101.title}}
</p>
</div>
<!-- dynamic form -->
<div class="col-md-12 borderBox boxLeft bg_box">
<form novalidate name="addForm">
<div class="boxLeft" ng-show="Question != ''">
<div ng-show="Question.infotip != 'yes'">
<h1 class="heading_left">{{Question.ask}}</h1>
</div>
<div ng-show="Question.infotip == 'yes'">
<h1 class="heading_left info">{{Question.ask}}
<span class="infotip yourData" tooltip-placement="top" tooltip-trigger="click" tooltip="{{Question.infotipText}}"></span>
</h1>
</div>
</div>
<div class="boxRight" ng-show="Question != ''">
<button class="btn btn-lg btn-default next bt_submits" type="button" ng-click="addData(newData)">
<span class="bt_arrow"></span>
</button>
</div>
<div class="boxRejestracjaInput">
<!-- <div id="legg-select" ng-if="Question.type === 'select'">
<select ng-options="opt.val for opt in Question.options" name="{{Question.name}}" ng-model="value" ng-keypress="enter($event,value.val)"></select>
</div> -->
<div class="newSelect">
<label ng-if="Question.type === 'select'">
<select ng-options="opt.val for opt in Question.options" name="{{Question.name}}" ng-model="value" ng-keypress="enter($event,value.val)"></select>
</label>
</div>
<input
ng-if="Question.type === 'text'"
type="{{Question.type}}"
name="institutionName"
class="inputName"
value="{{Question.value}}"
ng-model="value"
ng-minlength="{{Question.min}}"
ng-maxlength="{{Question.max}}"
ng-keypress="enter($event,value)"
placeholder="{{Question.placeholder}}"
ng-pattern="{{Question.pattern}}" />
<!-- <div class="custom-error institution" ng-show="addForm.institutionName.$error.minlength || addForm.institutionName.$error.maxlength">
Minimum {{Question.min}} znaków
</div> -->
<!-- <div class="custom-error institution" ng-show="addForm.institutionName.$error.maxlength">
Max {{Question.max}} znaków
</div> -->
<div class="custom-error institution" ng-show="addForm.institutionName.$error.pattern || addForm.institutionName.$error.maxlength || addForm.institutionName.$error.minlength">
{{Question.copy}}
</div>
</div>
</form>
</div>
<p>
{{lang.sec101.title2}}
</p>
<a href="rejestracja_10edit.html" class="btn btn-lg btn-default bt_edit" type="button">
{{lang.sec101.title3}}<span class="btn_bg_img"></span>
</a>
</div>
<div class="col-md-12 noPad" ng-repeat="sek in formOut">
<h3 class="daneHeading">{{sek.name}}</h3>
<div class="row">
<div class="col-md-12" >
<div class="col-md-4 col-sm-6 boxContent3 boxes" ng-repeat="row in sek.data">
<span class="leftBoxContrnt">{{row.shortAsk}}</h4></span>
<h4 class="rightBoxContrnt">{{row.value}}</h4>
</div>
</div>
</div>
</div>
<!-- <div class="row col-md-12" >
<h3 class="daneHeading">Hasło</h3>
</div>
<div class="row">
<div class="col-md-12 " >
<div class="col-md-4 col-sm-6 boxContent3">
<span class="leftBoxContrnt">Test</h4></span><span class="blueTxt"> *</span>
<h4 class="rightBoxContrnt">Test</h4>
</div>
</div>
</div> -->
</div>
my controller:
var app = angular.module('app', ['ngAnimate', 'ngCookies', 'ui.bootstrap', 'ngSanitize', 'nya.bootstrap.select', 'jackrabbitsgroup.angular-slider-directive']);
// var rej10_Controller = function($scope, $http, $cookieStore, $timeout, limitToFilter) {
app.controller('rej10_Controller', ['$scope', '$http', '$cookieStore', '$sce', '$timeout', 'limitToFilter',
function($scope, $http, $cookieStore, $sce, $timeout, limitToFilter) {
var view = 10,
arr,
data,
counterSection = 0,
counterAsk = 0;
$scope.opts = {};
$scope.slider_id = 'my-slider';
$scope.opts = {
'num_handles': 1,
'user_values': [0, 1],
'slider_min': 0,
'slider_max': 1,
'precision': 0,
};
/* language */
if (!$cookieStore.get('lang'))
$cookieStore.put('lang', 'pl');
var lang = $cookieStore.get('lang');
$scope.language = lang;
$scope.setLang = function(data) {
$cookieStore.put('lang', data);
$http.get('../widoki/json/lang/' + data + '/rej_' + view + '.json').
success(function(data, status, headers, config) {
$scope.lang = data;
$scope.Question = $scope.lang.formIn.sekcja[counterSection].data[counterAsk];
console.log($scope.lang);
}).
error(function(data, status, headers, config) {
console.log('error load json');
});
$scope.language = data;
};
/* get language pack */
$http({
method: 'GET',
url: '../widoki/json/lang/' + lang + '/rej_' + view + '.json'
}).
success(function(data, status, headers, config) {
$scope.lang = data;
$scope.Question = $scope.lang.formIn[counterSection].data[counterAsk];
$scope.langLen = $scope.lang.formIn.length;
}).error(function(data, status, headers, config) {
console.log('error load json');
});
/* dynamic form */
$scope.enter = function(ev, d) {
if (ev.which == 13) {
$scope.addData(d);
}
};
$scope.addData = function(data) {
var newData = {};
/* latamy po id sekcji i po id pytania */
if (!$scope.formOut) {
$scope.formOut = [];
}
/* budowanie modelu danych wychodzcych */
newData = {
sekcja: counterSection,
name: $scope.lang.formIn[counterSection].name,
data: []
};
console.log(name);
if (!$scope.formOut[counterSection]) {
$scope.formOut.push(newData);
}
$scope.formOut[counterSection].data.push($scope.Question);
$scope.formOut[counterSection].data[counterAsk].value = data;
counterAsk++;
// zmieniamy sekcje
if (counterAsk == $scope.lang.formIn[counterSection].data.length) {
counterAsk = 0;
counterSection++;
}
if (counterSection == $scope.lang.formIn.length) {
$scope.Question = '';
/* zrobic ukrycie pola z formularza */
} else {
$scope.Question = $scope.lang.formIn[counterSection].data[counterAsk];
}
/* konwertowanie do jsona */
//var Json = angular.toJson($scope.formOut);
//console.log(Json);
};
$scope.submit = function() {
alert('form sent'); /* wysĹanie formularza */
};
$scope.getClass = function(b) {
return b.toString();
};
}
]);
app.directive('ngEnter', function() {
return function(scope, element, attrs) {
element.bind("keydown keypress", function(event) {
if (event.which === 13) {
scope.$apply(function() {
scope.$eval(attrs.ngEnter);
});
event.preventDefault();
}
});
};
});
app.config(['$tooltipProvider',
function($tooltipProvider) {
$tooltipProvider.setTriggers({
'mouseenter': 'mouseleave',
'click': 'click',
'focus': 'blur',
'never': 'mouseleave',
'show': 'hide'
});
}
]);
var ValidSubmit = ['$parse',
function($parse) {
return {
compile: function compile(tElement, tAttrs, transclude) {
return {
post: function postLink(scope, element, iAttrs, controller) {
var form = element.controller('form');
form.$submitted = false;
var fn = $parse(iAttrs.validSubmit);
element.on('submit', function(event) {
scope.$apply(function() {
element.addClass('ng-submitted');
form.$submitted = true;
if (form.$valid) {
fn(scope, {
$event: event
});
}
});
});
scope.$watch(function() {
return form.$valid
}, function(isValid) {
if (form.$submitted == false)
return;
if (isValid) {
element.removeClass('has-error').addClass('has-success');
} else {
element.removeClass('has-success');
element.addClass('has-error');
}
});
}
};
}
};
}
];
app.directive('validSubmit', ValidSubmit);
I cant figure out what is the problem.
Thanks in advance.
Try changing your ngClick button handler to an ngSubmit form handler and wiring that up. You didn't say what browser you're using, but most of them auto-submit forms on an ENTER keypress unless you trap it (which you aren't). Clicking a button won't do this.

Accessing parent $scope

I have posted earlier this post with the choice of not providing all my code. But now im stuck since with the same problem so I give it a change with providing all my code.
I know its not easy to debug when the code is huge so I will try to explain precisely the problem.
Actually the problem is described in my precedent post so please read it and look at the code that is a simplification of this one.
But basically the problem is : I want to access $scope.data.comments from the $scope.deleteComment() function
As you see the code below you will notice that I have to add ng-controller="CommentController" twice for this to work.
If someone could explain why.. that would be great but I guess that is another question.
Thanks in advance for your help.
MAIN HTML
<div ng-init="loadComments('${params.username}', '${params.urlname}' )" ng-controller="CommentController">
<div ng-repeat="comments in data.comments" >
<div sdcomment param="comments" ></div>
</div>
</div>
APP
var soundshareApp = angular.module('soundshareApp', ['ngCookies']);
DIRECTIVES
soundshareApp.directive('sdcomment', ['$cookies', function($cookies){
var discussionId = null;
var found = false;
var username = $cookies.soundshare_username;
return {
restrict:'A',
scope: {
commentData: '=param'
},
templateUrl: '/js/views/comment/templates/commentList.html',
link : function(scope, element, attrs, controller) {
scope.$watch(element.children(), function(){
var children = element.children();
for(var i=0; i<children.length; i++){
if(children[i].nodeType !== 8){ //pas un commentaire <!-- -->
if( !found ){
found = true;
discussionId == scope.commentData.discussionId
}else if(found && discussionId == scope.commentData.discussionId){
angular.element(children[i]).removeClass('message-content');
angular.element(children[i]).addClass('answer-message-content');
}
if(found && discussionId != scope.commentData.discussionId){
discussionId = scope.commentData.discussionId
}
if(username == scope.commentData.username){
element.parent().bind('mouseover', function() {
// $(".delete-comment-button").show()
element.parent().find("span.delete-comment-button:first").attr('style', 'display: block !important');
});
element.parent().bind('mouseleave', function() {
element.parent().find("span.delete-comment-button:first").attr('style', 'none: block !important');
});
}
}
}
});
}
}
}]);
TEMPLATE
<div class="message-wrapper" ng-controller="CommentController">
<div class='message-content' ng-click="state.show = !state.show; setUsername(commentData.username)">
<img class='message-vignette' ng-src='{{commentData.avatarUrl}}'/>
<div class='message-username'>{{commentData.username}}</div>
<div class='project-message'>{{commentData.comment}}</div>
<div class='message-date'>{{commentData.dateCreated | date:'dd.MM.yyyy # hh:mm:ss' }}</div>
<div class="clearfix"></div>
</div>
<div ng-repeat="answer in answers" class="answer-message-content" >
<div class='message-content' ng-click="state.show = !state.show">
<img class='message-vignette' ng-src='{{answer.avatarUrl}}'/>
<div class='message-username'>{{answer.username}}</div>
<div class='project-message'> {{answer.comment}}</div>
<div class='message-date'>{{answer.dateCreated | date:'MM/dd/yyyy # h:mma' }}</div>
<div class="clearfix"></div>
</div>
</div>
<div class="add-comment-content show-hide" ng-show="state.show" >
<img class='message-vignette answer-message-vignette' ng-src='{{commentData.currentUserAvatarUrl}}'>
<div class="">
<form ng-submit="addComment(commentData)" id="commentForm-{{commentData.projectId}}">
<input id="input-comment-{{commentData.projectId}}" type="text" maxlength="" autofocus="autofocus" name="comment" placeholder="Write a comment..." ng-model="commentData.msg">
<input type="hidden" name="discussionId" value="{{commentData.discussionId}}" >
<input type="hidden" name="projectId" value="{{commentData.projectId}}" >
</form>
</div>
</div>
<span ng-click="deleteComment(commentData)" class="btn btn-default btn-xs delete-comment-button"><i class="icon-trash"></i></span>
</div>
CONTROLLER
'use strict';
soundshareApp.controller('CommentController', function($scope, $http) {
$scope.data = { comments : [] }
$scope.answers = [];
$scope.state = {}
$scope.project = { id : [] }
$scope.username = null;
$scope.loadComments = function(userName, urlName){
$http({
url: '/comment/by_project_id',
method: "GET",
params:
{
username: userName,
urlname: urlName
}
}).success(function(data) {
$scope.data.comments = data;
console.log($scope.data.comments);//WORKING
});;
}
$scope.addComment = function(commentData){
if("undefined" != commentData.msg){
commentData.msg = "#" + $scope.username + ": " + commentData.msg;
$http({
method : "POST",
url : "/comment/addAnswer",
params:
{
comment: commentData.msg,
discussionId: commentData.discussionId,
projectId:commentData.projectId
}
}).success(function(data){
$scope.answers.push(data);
$('.show-hide').hide();
$scope.commentData.msg = '';
});
}
}
$scope.setUsername = function(username){
$scope.username = username;
}
$scope.deleteComment = function ( comment ) {
console.log($scope.data.comments);//NOT WORKING
};
});

Resources