cursor moves to new generated textbox in angualarjs - angularjs

I have form with modal, When i click enter or add email button it generates the new text box but cursor will not move into that text box.
But i need when i click enter or add email button, then cursor automatically should move to the newly generated text box.
My html code
<script type="text/ng-template" id="myModalContent">
<div class="modal-header">
<h3 class="modal-title">I'm a modal!</h3>
</div>
<div class="modal-body">
<li ng-repeat="item in items " ng-form="subForm">
<input type="text" name="name" ng-model="item.email" required ng-pattern="/^[_a-z0-9]+(\.[_a-z0-9]+)*#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$/" ng-enter="addOrRemove($index,item.email)"/>
<span ng-show="subForm.name.$error.required" style="color: red">Email required</span>
<span ng-show="subForm.name.$invalid" ng-hide="subForm.name.$error.required" style="color: red">Invalid email</span>
<button ng-disabled="subForm.name.$invalid || subFform.name.$dirty" ng-click="addOrRemove($index,item.email)" >{{item.value}}</button>
expression: {{subForm.name.$invalid}}
</li>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="ok()">OK</button>
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>
</script>
My javascript code
$scope.addOrRemove = function(indexSelected,rcvEmail)
{//alert($rootScope.email1);
if(!rcvEmail)
{
return
}
console.log("just check email",rcvEmail);
console.log("length of the object",$scope.items.length);
event.preventDefault();
if($scope.items[indexSelected].state == 1)
{
//console.log($scope.items[indexSelected].state);
$scope.items[indexSelected].value = "Remove email";
$scope.items[indexSelected].state = "0";
$scope.items[indexSelected].email = rcvEmail;
$scope.items.push({value: "Add email", state: "1"});
}
else
{
//console.log($scope.items[indexSelected].state);
//$scope.items.push({value: "Remove email", state: "1"});
$scope.items.splice(indexSelected, 1);
}
};
see the code here

In order to focus an input you have to create custom directive.
.directive('focus', function($timeout, $parse) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
scope.$watch(attrs.focus, function(newValue, oldValue) {
if(newValue) {
element[0].focus();
}
});
element.bind("blur", function(e) {
$timeout(function() {
scope.$apply(attrs.focus + "=false");
}, 0);
});
element.bind("focus", function(e) {
$timeout(function() {
scope.$apply(attrs.focus + "=true");
}, 0);
})
}
}
})
And then you can use it in the input.
<input type="text" ng-init="inp_focus = true" focus="inp_focus" />
Please check this example.
http://jsfiddle.net/Serhioromano/bu2k2cb7/

Related

Angular: Passed params in nested directive is of state "undefined"

We are following an example from http://mfauveau.github.io/angular-query-builder/ and modifying it to fit into our requirement.
We have a modal view(.jsp) that has integrated directive (named as 'querybuilder', Yellow part in the picture - a js file). Controller(named as 'addEditRuleSetCtrl') and directive is included from upper level and inclusion seems fine.
We have initiated the directive from the view (.jsp file)as :
<div ng-init="addEditRuleSetCtrl.initSelectors()">
<query-builder group="addEditRuleSetCtrl.filter.group"
rule-condition-operators="addEditRuleSetCtrl.ruleConditionOperators"
rule-condition-set-operators="addEditRuleSetCtrl.ruleConditionSetOperators"
fields="addEditRuleSetCtrl.getCorrespondingFields()"
></query-builder>
</div>
And we have included the template for the directive in view/.jsp as (notice that the directive is initiated here again when new group is created):
<script type="text/ng-template" id="/queryBuilderDirective.html">
<div class="alert alert-warning alert-group">
<div class="form-inline">
<select ng-options="o as o.operator for o in ruleConditionSetOperators" ng-model="group.operator" class="form-control input-sm"></select>
<button style="margin-left: 5px" ng-click="addCondition()" class="btn btn-sm btn-success"><span class="glyphicon glyphicon-plus-sign"></span> Add Condition</button>
<button style="margin-left: 5px" ng-click="addGroup()" class="btn btn-sm btn-success"><span class="glyphicon glyphicon-plus-sign"></span> Add Group</button>
<button style="margin-left: 5px" ng-click="removeGroup()" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-minus-sign"></span> Remove Group</button>
</div>
<div class="group-conditions">
<div ng-repeat="rule in group.rules | orderBy:'index'" class="condition">
<div ng-switch="rule.hasOwnProperty('group')">
<div ng-switch-when="true">
<query-builder group="rule.group"
rule-condition-operators="addEditRuleSetCtrl.ruleConditionOperators"
rule-condition-set-operators="addEditRuleSetCtrl.ruleConditionSetOperators"
fields="addEditRuleSetCtrl.getCorrespondingFields()"
></query-builder>
</div>
<div ng-switch-default="ng-switch-default">
<div class="form-inline">
<select ng-options="t.name as t.name for t in fields" ng-model="rule.field" class="form-control input-sm"></select>
<select style="margin-left: 5px" ng-options="c as c.operator for c in ruleConditionOperators" ng-model="rule.condition" class="form-control input-sm"></select>
<input style="margin-left: 5px" type="text" ng-model="rule.data" class="form-control input-sm"/>
<button style="margin-left: 5px" ng-click="removeCondition($index)" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-minus-sign"></span></button>
</div>
</div>
</div>
</div>
</div>
</div>
Our problem is : the first layer of the tree/group has right value of all the parameters(fields,rule-condition-set-operators,rule-condition-operators). Hence, in the first layer , all the associated dropdowns have displayed right values. But when I click the button "add group" in the first layer, all the params are now "undefined" and hence all the dropdowns starting from the 2nd layer is empty ( showed by the red arrow sign in the picture).
Questions are :
Is that correct that starting from the 2nd layer of group, the
params are out of scope of the controller because they are defined
outside the view block?
How to make the params available to all layers of the group?
Here is the view (.jsp file):
<%# page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="UTF-8"%>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<link
href="<c:url value='aviato/ruleEngine/addEditRuleSet/css/addeditruleset.css' />"
rel="stylesheet">
</link>
<%--<script src="aviato/ruleEngine/addEditRuleSet/directive/addEditRuleSet_directive.js"></script>--%>
<form name="addEditRuleSetModalForm" novalidate class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">
{{addEditRuleSetCtrl.windowHeader}}
<button type="button" class="btn btn-danger btn-sm pull-right"
ng-click="addEditRuleSetCtrl.close()" data-toggle="uibtooltip" title="Cancel" >
<span class="glyphicon glyphicon-remove-sign"></span>
</button>
</h4>
</div>
<div class="modal-body">
Hello world [origin] : {{ addEditRuleSetCtrl.origin }}
<br />
Hello world [iceField] : {{ addEditRuleSetCtrl.iceField }}
Output: {{ addEditRuleSetCtrl.output }}
<div class="alert alert-info">
<strong>Example Output</strong><br>
Output: {{ addEditRuleSetCtrl.output }}
</div>
<div ng-init="addEditRuleSetCtrl.initSelectors()">
<query-builder group="addEditRuleSetCtrl.filter.group"
rule-condition-operators="addEditRuleSetCtrl.ruleConditionOperators"
rule-condition-set-operators="addEditRuleSetCtrl.ruleConditionSetOperators"
fields="addEditRuleSetCtrl.getCorrespondingFields()"
></query-builder>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary btn-sm" ng-click="addEditRuleSetCtrl.test()" data-toggle="tooltip" ><span class="glyphicon glyphicon-ok-sign" ></span></button><span></span>
</div>
</div>
</form>
<script type="text/ng-template" id="/queryBuilderDirective.html">
<div class="alert alert-warning alert-group">
<div class="form-inline">
<select ng-options="o as o.operator for o in ruleConditionSetOperators" ng-model="group.operator" class="form-control input-sm"></select>
<button style="margin-left: 5px" ng-click="addCondition()" class="btn btn-sm btn-success"><span class="glyphicon glyphicon-plus-sign"></span> Add Condition</button>
<button style="margin-left: 5px" ng-click="addGroup()" class="btn btn-sm btn-success"><span class="glyphicon glyphicon-plus-sign"></span> Add Group</button>
<button style="margin-left: 5px" ng-click="removeGroup()" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-minus-sign"></span> Remove Group</button>
</div>
<div class="group-conditions">
<div ng-repeat="rule in group.rules | orderBy:'index'" class="condition">
<div ng-switch="rule.hasOwnProperty('group')">
<div ng-switch-when="true">
<query-builder group="rule.group"
rule-condition-operators="addEditRuleSetCtrl.ruleConditionOperators"
rule-condition-set-operators="addEditRuleSetCtrl.ruleConditionSetOperators"
fields="addEditRuleSetCtrl.getCorrespondingFields()"
></query-builder>
</div>
<div ng-switch-default="ng-switch-default">
<div class="form-inline">
<select ng-options="t.name as t.name for t in fields" ng-model="rule.field" class="form-control input-sm"></select>
<select style="margin-left: 5px" ng-options="c as c.operator for c in ruleConditionOperators" ng-model="rule.condition" class="form-control input-sm"></select>
<input style="margin-left: 5px" type="text" ng-model="rule.data" class="form-control input-sm"/>
<button style="margin-left: 5px" ng-click="removeCondition($index)" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-minus-sign"></span></button>
</div>
</div>
</div>
</div>
</div>
</div>
</script>
The Directive (.js file):
AddEditRuleSetApp.directive('queryBuilder', ['$compile', function ($compile) {
return {
restrict: 'E',
scope: {
group: '=',
ruleConditionOperators: '=',
ruleConditionSetOperators: '=',
fields: '='
},
templateUrl: '/queryBuilderDirective.html',
compile: function (element, attrs) {
var content, directive;
content = element.contents().remove();
return function (scope, element, attrs) {
scope.addCondition = function () {
window.alert("[addCondition] : " + "group : " + JSON.stringify( scope.group) + "...BREAK..."
+"fields : " + JSON.stringify( scope.ruleConditionOperators) + "...BREAK..."
+"Condition : "+JSON.stringify(scope.ruleConditionOperators) + "...BREAK..."
+"Condition set: "+JSON.stringify(scope.ruleConditionSetOperators));
scope.group.rules.push({
condition: '=',
field: 'Firstname',
data: ''
});
};
scope.removeCondition = function (index) {
scope.group.rules.splice(index, 1);
};
scope.addGroup = function () {
window.alert("[addGroup] :" + "group : " + JSON.stringify( scope.group) + "...BREAK..."
+" fields : " + JSON.stringify( scope.fields) + "...BREAK..."
+"Condition : "+JSON.stringify(scope.ruleConditionOperators) + "...BREAK..."
+"Condition set: "+JSON.stringify(scope.ruleConditionSetOperators));
scope.group.rules.push({
group: {
operator: 'AND',
rules: []
}
});
};
scope.removeGroup = function () {
"group" in scope.$parent && scope.$parent.group.rules.splice(scope.$parent.$index, 1);
};
directive || (directive = $compile(content));
element.append(directive(scope, function ($compile) {
return $compile;
}));
}
}
}
}]);
The controller :
AddEditRuleSetApp.controller( 'AddEditRuleSetModalController', [ '$scope', '$rootScope', '$uibModalInstance','RuleEngineService', 'origin', 'iceField','FileService',
function( $scope, $rootScope , $uibModalInstance, RuleEngineService, origin, iceField, FileService )
{
var self = this;
self.origin = origin;
self.iceField = iceField;
self.data = '{"group": {"operator": "AND","rules": []}}';
self.output = 'bologna';
self.fieldsDDE = [
{ name: 'FirstnameDDE' },
{ name: 'LastnameDDE' },
{ name: 'BirthdateDDE' },
{ name: 'CityDDE' },
{ name: 'CountryDDE' }
];
self.fieldsATT = [
{ name: 'FirstnameATT' },
{ name: 'LastnameATT' },
{ name: 'BirthdateATT' },
{ name: 'CityATT' },
{ name: 'CountryATT' }
];
self.ruleConditionSetOperators = [
];
self.ruleConditionOperators = [
];
self.filter = JSON.parse(self.data);
self.initSelectors = function()
{
self.getRuleConditionOperators();
self.getRuleConditionSetOperators();
}
self.getRuleConditionOperators = function()
{
if ( self.ruleConditionOperators.length == 0 )
{
RuleEngineService.getAllRuleConditionOperators()
.then(
function( d )
{
self.ruleConditionOperators = d;
},
function( errResponse )
{
console.error( 'Error while fetching rule-condition-operators' );
}
);
}
return self.ruleConditionOperators;
};
self.getRuleConditionSetOperators = function()
{
if ( self.ruleConditionSetOperators.length == 0 )
{
RuleEngineService.getAllRuleConditionSetOperators()
.then(
function( d )
{
self.ruleConditionSetOperators = d;
},
function( errResponse )
{
console.error( 'Error while fetching rule-condition-operators' );
}
);
}
return self.ruleConditionSetOperators;
};
self.htmlEntities = function(str)
{
return String(str).replace(/</g, '<').replace(/>/g, '>');
};
self.displayErrorMessages = false;
self.createSuccess = '';
self.createHeader = '';
self.backendErr = "";
self.windowHeader = "Create/Edit Rule Group";
self.close = function()
{
$uibModalInstance.close();
};
self.getCorrespondingFields = function()
{
// window.alert("---------------Reached client side controller to getCorrespondingFields");
return self.origin == 'DDE' ? self.fieldsDDE : self.fieldsATT;
};
self.computed = function(group)
{
window.alert("Inside controller: computed");
if (!group) return "";
for (var str = "(", i = 0; i < group.rules.length; i++) {
i > 0 && (str += " <strong>" + group.operator + "</strong> ");
str += group.rules[i].group ?
self.computed(group.rules[i].group) :
group.rules[i].field + " " +
//htmlEntities(group.rules[i].condition)
group.rules[i].condition
+ " " + group.rules[i].data;
}
return str + ")";
};
$scope.$watch('filter', function (newValue)
{
self.output = self.computed(newValue);
}, true);
self.test = function()
{
window.alert(JSON.stringify( self.filter) );
};
}
]);
The screenshot:
May I get any help here? Thanks in advance.
This is my workaround (Addeed this to the directive) and that helped:
scope.fieldCodes = scope.$parent.fieldCodes;
scope.ruleConditionOperators = scope.$parent.ruleConditionOperators;
scope.ruleConditionSetOperators = scope.$parent.ruleConditionSetOperators;
So, the directive now looks like:
AddEditRuleSetApp.directive('queryBuilder', ['$compile', function ($compile) {
return {
restrict: 'E',
scope: {
group: '=',
ruleConditionOperators: '=',
ruleConditionSetOperators: '=',
fieldCodes: '='
},
templateUrl: '/queryBuilderDirective.html',
compile: function (element, attrs) {
var content, directive;
content = element.contents().remove();
return function (scope, element, attrs) {
scope.fieldCodes = scope.$parent.fieldCodes;
scope.ruleConditionOperators = scope.$parent.ruleConditionOperators;
scope.ruleConditionSetOperators = scope.$parent.ruleConditionSetOperators;
scope.addCondition = function () {
scope.group.rules.push({
condition: '=',
field: 'Firstname',
data: ''
});
};
scope.removeCondition = function (index) {
scope.group.rules.splice(index, 1);
};
scope.addGroup = function () {
scope.group.rules.push({
group: {
operator: 'AND',
rules: []
}
});
};
scope.removeGroup = function () {
"group" in scope.$parent && scope.$parent.group.rules.splice(scope.$parent.$index, 1);
};
directive || (directive = $compile(content));
element.append(directive(scope, function ($compile) {
return $compile;
}));
}
}
}
}]);

Popover close when click on its body,How to disable?

Popover content always close when click to focus cursor on Popover body
here my popover directive
angular.module('collect').directive('popover', function($timeout){
return {
restrict : 'E',
replace : true,
link: function(scope, element, attrs) {
var popover = null;
// define popover for this element
$timeout(function() {
// TODO: maybe can continue using $(element) or just element instead of saving popover var
popover = $(element).popover({
html: true,
placement: scope.placement || "top",
// grab popover content from the next element
content: $(element).siblings(".pop-content").contents(),
});
popover.on('show.bs.popover', function($event) {
//hide any visible popover
$('.popover').not($(element)).popover('hide');
});
},0 , false);
var unbinder = scope.$on(
"$destroy",
function handleDestroyEvent() {
if (popover) {
popover.off('show.bs.popover');
popover = null;
}
$(element).off('.popover.data-api'); // TODO: I think this is only for jquery, not bootstrap
$(element).popover('destroy');
element.remove();
unbinder();
}
);
$("body").on("click touchstart", '.popover', function() {
$(this).popover("show");
$('.popover').not(this).popover("hide"); // hide other popovers
return false;
});
}
};
});
and this one is how I use popover
<span>
<popover class="tbl-act-btn action-column action-column-ic popover-btn" title="Comments">
<span title="{{columnName}}">
<i class="fa" ng-class="{'fa-comments-o' : !isComment(commentContentTemp), 'fa-comments' : isComment(commentContentTemp)}"></i>
</span>
</popover>
<div ng-hide="true" class="pop-content">
<div class="form-group">
<textarea class="popover-textarea form-control" name="comment" ng-model="commentContentTemp"></textarea>
<div class="popover-footer">
<button type="button"
class="glyphicon glyphicon-ok btn btn-primary popover-submit" aria-hidden="true" ng-click="updateComment($event)"></button>
<button type="button" class="glyphicon glyphicon-remove btn btn-default popover-cancel" aria-hidden="true" ng-click="cancelUpdateComment($event)"></button>
</div>
</div>
</div>
It always close Popover when I click on textArea to edit text. I want it close whenever click on update, cancel, or outside Popover.

Broadcast from directive to controller

I am trying to modify a form in a view by means of a button in my directive's template (template is in another file), this is for a basic CRUD where each item has a delete/edit button.
In order to avoid replicating the form I decided to that on edit's click a function would send the item to the controller in questions in order to be updated with the new information.
But I've been having troubles making the connection, so far I tried changing $root, to $rootScope back and forth and using , $broadcast or $emit.
So how can I send the function onChange my item's information based on the template's button click?
Template:
<strong>{{item.type}}</strong> {{item.description}}
<div class="material-switch pull-right">
<button type="button" class="btn btn-warning btn-circle" ng-show="item.editable" ng-click="onChange()">
<span class="glyphicon glyphicon-edit" ></span>
</button>
<button type="button" class="btn btn-danger btn-circle" ng-controller="View1Ctrl" ng-show="item.editable" ng-click="EliminarItem(item)">
<span class="glyphicon glyphicon-minus" ></span>
</button>
<input ng-model="item.isDone"
id="someSwitchOptionDefault{{itemIndex}}"
name="someSwitchOption001{{itemIndex}}"
type="checkbox" />
<label for="someSwitchOptionDefault{{itemIndex}}" class="label-info"></label>
</div>
Directive:
'use strict';
angular.module('myApp.items.directive', [])
.directive('itemSwitch', [ function() {
return {
restrict: 'A',
scope: {
item: '=',
itemIndex: "="
},
templateUrl: 'templates/itemSwitchTemplate.html',
link : function($scope){
$scope.$broadcast('onChange', item);
}
}
}]);
Controller
.controller('View1Ctrl', ['$scope','itemsService',function($scope,itemsService) {
$scope.items = itemsService.getItems();
$scope.classMap = {GROCERIES:"success",CAR:"danger",UNIVERSITY:"warning",PAYMENTS:"info"};
$scope.newItem = {};
$scope.$on('onChange', function(event, args) {
if ($scope.btnEdit) {
$scope.newItem = args;
} else {
$scope.newItem = {};
}
});
$scope.enableEdit = function (item) {
item.editable = true;
};
$scope.disableEdit = function (item) {
item.editable = false;
};
}]);
View
<div class="col-xs-12">
<div ng-model="currentItem" ng-repeat="item in items" item-switch item="item" item-index="$index" class="notice notice-{{classMap[item.type]}}" ng-mouseover="enableEdit(item)" ng-mouseleave="disableEdit(item)">
</div>
<!-- FORMULARIO -->
<form name = "myForm" class="form-horizontal">
<fieldset>
<div id="legend">
<legend class="">Task</legend>
</div>
<div class="control-group">
<!-- Name-->
<label class="control-label">Name</label>
<div class="controls">
<input type="text" name="itemName" ng-model="newItem.name" placeholder="Task Name" class="input-xlarge" ng-required="true" >
<p class="help-block"></p>
</div>
</div>
<div class="control-group">
<!-- Description -->
<label class="control-label">Description</label>
<div class="controls" >
<input type="text" ng-model="newItem.description" placeholder="Task Description" class="input-xlarge">
<p class="help-block"></p>
</div>
</div>
<div class="control-group">
<!-- Button -->
<div class="controls">
<a class="btn icon-btn btn-success" ng-disabled="myForm.$invalid" ng-click="addOrSaveItem()">
<span class="glyphicon btn-glyphicon glyphicon-save img-circle text-success"></span>Save</a>
</div>
</div>
</fieldset>
</form>
</div>
FiddleJS
Look nd Feel
Using "onChange" as an event name is a poor choice as it is likely to conflict with other events with that name. My recommendation is to use the directive's name as part of the event name.
In your directive
angular.module('myApp.items.directive', [])
.directive('itemSwitch', function() {
return {
restrict: 'A',
scope: {
item: '=',
itemIndex: "="
},
template: '<button ng-click="doIt()">Do It</button>',
link : function(scope){
scope.doIt = function() {
scope.$emit('itemSwitch.doIt', scope.item, scope.itemIndex);
};
}
}
});
In your controller
$scope.doItItems = [];
$scope.$on("itemSwitch.doIt", function(item, itemIndex) {
doItItems.push(item);
});
In this example, on each click of the Do It button, an item is pushed to the doItItems list.
In your itemSwitch directive, you can do
$rootScope.$broadcast('onChange', item);
And then you can pick it up in any scope that is listening (in this case, your controller), with
$scope.$on('onChange', function(event, args) { ... }
This works because $broadcast moves downward from parent to children, while $emit moves upward from child to parents.
So for example, $rootScope.$emit would only be picked up by $rootScope.$on since $rootScope has no parents, while $scope.$broadcast would only be available to that scope's children and not to $rootScope.$on, since $rootScope is not a child of $scope

AngularJS: upload file inside modal-ui-bootstrap

I have an angular modal-ui, in it I upload file. The problem is that for some reason the <input> of the file doesn't triggers the app directive. The directive returns the file name and size when the <input> being changed.
this is the result I want to get:
example
I really tried already any thing, but still for some reason I can't see in the <span> the file name.
The html file :
<form novalidate ng-submit="add(Form.$valid)" name="Form">
<div class="modal-header col-lg-12">
<h3 class="col-lg-4 col-lg-offset-4">add file</h3>
</div>
<div class="modal-body">
<div class="panel-body">
<div class="row">
<div class="form-group col-lg-8" ng-class="{'has-error': notPass && Form.fileName.$invalid}">
<label class="control-label label-add-card" for="fileName">name</label>
<input class="input-add-card form-control " id="fileName" name="fileName" type="text" ng-model="fileName" ng-pattern="/^[a-z1-9]{10,}$/" ng-required="true">
<p ng-show="notPass && Form.fileName.$invalid" class="help-block">not good</p>
</div>
</div>
<div class="row">
<div class="form-group col-lg-8" ng-class="{'has-error':notPass && Form.fileExplain.$invalid}">
<label class="control-label label-add-card" for="fileExplain">explain</label>
<textarea class="input-big form-control " id="fileExplain" name="fileExplain" type="text" ng-model="fileExplain" ng-pattern="/^[a-z1-9]{1,}$/" ng-required="true"></textarea>
<p ng-show="notPass && Form.fileExplain.$invalid" class="help-block">not good</p>
</div>
</div>
<div>
<div class="form-group col-lg-12" ng-class="{'has-error':notPass && Form.uploadDownloads.$invalid}">
<input ng-model="uploadDownloads" type="file" fd-input file-name="fileName" />
<input class="btn btn-primary" type="button" value="choose" onclick="$(this).parent().find('input[type=file]').click();"/> <!-- on button click fire the file click event -->
<span class="badge badge-important">{{fileName}}</span>
<p ng-show="notPass && Form.uploadDownloads.$invalid" class="help-block">please choose</p>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-success col-lg-12 btn-modal-costume">add</button>
</div>
</form>
the modal controller:
/**
* Created by Ariel on 22/11/2015.
*/
app.controller('uploadDownloadsController',function($scope,$modalInstance ){
app.directive('fdInput', fdInput);
function fdInput() {
return {
scope: {
fileName: '='
},
link: function(scope, element, attrs) {
element.on('change', function(evt) {
var files = evt.target.files;
console.log(files[0].name);
console.log(files[0].size);
scope.fileName = files[0].name;
scope.$apply();
});
}
}
};
$scope.fileName = '';
$scope.add = function(valid){
if(valid){
$scope.data = 'none';
var f = document.getElementById('uploadDownloads').files[0];
var r = new FileReader();
r.onloadend = function(e){
$scope.data = e.target.result;
$scope.notPass = false;
$modalInstance.close({
'data':$scope.data,
'fileName':$scope.fileName,
'fileExplain':$scope.fileExplain
});
};
/*activate the onloadend to catch the file*/
r.readAsBinaryString(f);
} else {
$scope.notPass = true;
}
};
$scope.cancel = function() {
$modalInstance.dismiss('cancel');
};
});
here is how I have done it :
the html :
<form novalidate ng-submit="add(Form.$valid)" name="Form">
.
.
.
<div>
<div class="form-group col-lg-12" ng-class="{'has-error':notPass && Form.uploadDownloads.$invalid}">
<input ng-model="uploadDownloads" class="form-control-file" id="uploadDownloads" type="file" fd-input file-names="fileNames" />
<input class="btn btn-primary" type="button" value="choose" ng-click="choose()"/> <!-- on button click fire the file click event -->
<span class="badge badge-important">{{fileNames}}</span>
<p ng-show="notPass && Form.uploadDownloads.$invalid" class="help-block">you have to choose file</p>
</div>
</div>
.
.
.
</form>
I built a direcvtive to show thee file name dorring the upload:
/*get and shows the file name*/
app.directive('fdInput', function($timeout){
return {
scope: {
fileNames: '='
},
link:function(scope, element, attrs) {
$timeout(element.on('change', function(evt) {
var files = evt.target.files;
scope.fileNames = files[0].name;
scope.$apply();
}),0);
}
}
});
and this is the upload file controller:
app.controller('uploadDownloadsController',function($scope,$modalInstance,$timeout){
$scope.fileNames = '';
$scope.choose = function(){
$('#uploadDownloads').trigger('click');
};
$scope.add = function(valid){
if(valid){
$scope.data = 'none';
$scope.notPass = false;
/*this catches the file*/
var fileInput = document.getElementById('uploadDownloads');
var file = fileInput.files[0];
/* to send the file and the other inputs about it, need to use formData type*/
var formData = new FormData();
formData.append('file', file);
formData.append('fileName', $scope.fileName);
formData.append('fileExplain', $scope.fileExplain);
console.log(formData);
$modalInstance.close(formData);
} else {
$scope.notPass = true;
}
};
$scope.cancel = function() {
$modalInstance.dismiss('cancel');
};
});

Bind values to UI Bootstrap Modal

I have a table with a view button, when view is clicked modal display but now I want to display certain data on the modal. I am using .html pages.
I am not sure what am I missing here
html
<td>
<span>
<input class="btn btn-sm btn-dark" data-ng-click="launch('create',client)" type="button" value="view" />
</span>
</td>
This will luanch the modal
Modal
<div class="modal fade in" ng-controller="dialogServiceTest">
<div class="modal ng-scope">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">
<span class="glyphicon glyphicon-star"></span> Client Details
</h4>
</div><div class="modal-body">
<ng-form name="nameDialog" novalidate="" role="form" class="ng-pristine ng-invalid ng-invalid-required">
<div class="form-group input-group-lg" ng-class="{true: 'has-error'}[nameDialog.username.$dirty && nameDialog.username.$invalid]">
<label class="control-label" for="username">Name:</label>
<input type="text" name="username" id="username" ng-model="client.ClientName" ng-keyup="hitEnter($event)" required="">
<span class="help-block">Enter your full name, first & last.</span>
</div>
<div>{{client.ClientName}}</div>
</ng-form>
</div><div class="modal-footer">
<button type="button" class="btn btn-default" ng-click="cancel()">Cancel</button>
<button type="button" class="btn btn-primary" ng-click="save()" ng-disabled="(nameDialog.$dirty && nameDialog.$invalid) || nameDialog.$pristine" disabled="disabled">Save</button>
</div>
</div>
</div>
</div>
Angular
angular.module('modalTest', ['ngRoute','ui.bootstrap', 'dialogs'])
.controller('dialogServiceTest', function ($scope,$http, $rootScope, $timeout, $dialogs) {
$scope.clients = []; //Array of client objetcs
$scope.client = {}; //Single client object
$scope.launch = function (which,client) {
var dlg = null;
alert(client.ClientName);
dlg = $dialogs.create('/templates/Modal.html', 'whatsYourNameCtrl', {}, { key: false, back: 'static' });
dlg.result.then(function () {
$scope.client.ClientName = client.ClientName;
});
})
.run(['$templateCache', function ($templateCache) {
$templateCache.put('/templates/Modal.html');
}]);
here is some of my code
$scope.showScreenSizePicker = function(){
$scope.actionmsg = "";
var modalWindow = $modal.open({
templateUrl: '{{url()}}/modals/modalScreenSizePicker',
controller: 'modalScreenSizePickerController',
resolve: {
titletext: function() {return "Screen Sizes: ";},
oktext: function() {return "Close";},
canceltext: function() {return "Cancel";},
labeltext: function() {return "";},
}});
modalWindow.result.then(function(returnParams) {
$scope.setViewSize(returnParams[0], returnParams[1]);
});
}
you can see i am passing variables into modal using resolve. If you want to pass values back from the modal you can grab the variable returnParms (array)
and here is my controller code:
angular.module('myWebApp').controller('modalScreenSizePickerController', function($scope, $modalInstance, titletext, labeltext, oktext, canceltext) {
$scope.titletext = titletext;
$scope.labeltext = labeltext;
$scope.oktext = oktext;
$scope.canceltext = canceltext;
$scope.customHeight = 800;
$scope.customWidth = 600;
$scope.selectCustomSize = function(width, height){
if (width < 100){ width = 100; }
if (height < 100){ height = 100; }
$scope.selectItem(width, height);
}
$scope.selectItem = function(width, height) {
var returnParams = [width, height];
$modalInstance.close(returnParams);
};
$scope.cancel = function() {
$modalInstance.dismiss();
};
});
hope my sample helps
I think what you are looking for is the resolve property you can use with the $modal service. I am not exactly sure which version of UI Bootstrap you are using, but the latest one works as follows:
var myModal = $modal.open({
templateUrl: '/some/view.html',
controller: 'SomeModalCtrl',
resolve: {
myInjectedObject: function() { return someObject; }
});
myModal.result.then(function(){
// closed
}, function(){
// dismissed
});
Then you can use the injected resolved value inside the modals controller:
app.controller('SomeModalCtrl', function ($scope, $modalInstance, myInjectedObject) {
// use myInjectedObject however you like, eg:
$scope.data = myInjectedObject;
});
You can acces the client in modal by using "$scope.$parent.client" - "$parent" give you $scope from witch the modal was open with all data.

Resources