├── .editorconfig ├── .gitignore ├── .travis.yml ├── README.md ├── bower.json ├── demo ├── ajax-loader.gif ├── index.css ├── index.html └── index.js ├── dist ├── ng-inline-edit.css ├── ng-inline-edit.js ├── ng-inline-edit.min.css └── ng-inline-edit.min.js ├── gulpfile.js ├── package.json ├── src ├── scripts │ ├── controllers.js │ ├── directives.js │ ├── module.js │ └── providers.js └── styles │ └── ng-inline-edit.scss └── test ├── e2e.conf.js ├── e2e.travis.conf.js ├── karma.conf.js └── specs ├── e2e └── ng-inline-edit.js └── unit └── ng-inline-edit.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | 9 | # Change these settings to your own preference 10 | indent_style = space 11 | indent_size = 2 12 | 13 | # We recommend you to keep these unchanged 14 | end_of_line = lf 15 | charset = utf-8 16 | trim_trailing_whitespace = true 17 | insert_final_newline = true 18 | 19 | [*.md] 20 | trim_trailing_whitespace = false 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | bower_components 3 | coverage 4 | .tmp 5 | .idea/ 6 | .sass-cache 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: "0.10" 3 | env: 4 | - TRAVIS=true 5 | before_install: 6 | - "export DISPLAY=:99.0" 7 | - "sh -e /etc/init.d/xvfb start" 8 | - npm install --global gulp 9 | - npm install --global bower 10 | - npm install --global protractor 11 | - webdriver-manager update --standalone 12 | - webdriver-manager start & 13 | - bower install 14 | install: npm install 15 | script: gulp 16 | after_script: cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ng-inline-edit [![Build Status](http://img.shields.io/travis/tameraydin/ng-inline-edit/master.svg?style=flat-square)](https://travis-ci.org/tameraydin/ng-inline-edit) [![Code Climate](http://img.shields.io/codeclimate/github/tameraydin/ng-inline-edit.svg?style=flat-square)](https://codeclimate.com/github/tameraydin/ng-inline-edit/dist/ng-inline-edit.js) [![Coverage Status](https://img.shields.io/coveralls/tameraydin/ng-inline-edit/master.svg?style=flat-square)](https://coveralls.io/r/tameraydin/ng-inline-edit?branch=master) 2 | 3 | [Demo](http://tamerayd.in/ng-inline-edit/) 4 | 5 | ## Usage 6 | 7 | Install **ng-inline-edit** via [Bower](http://bower.io): 8 | ```bash 9 | bower install ng-inline-edit --production 10 | ``` 11 | 12 | Include main files: 13 | ```html 14 | 15 | 16 | ``` 17 | 18 | Include ``angularInlineEdit`` module as a dependency into your app: 19 | ```javascript 20 | angular 21 | .module('yourApp', [ 22 | 'angularInlineEdit' 23 | ]); 24 | ``` 25 | 26 | Pass your model to ``inline-edit`` attribute on your HTML element and provide a callback function to listen changes: 27 | ```html 28 | 29 | 41 | ``` 42 | 43 | ## Development 44 | 45 | See the instructions at [ng-pack](https://github.com/tameraydin/ng-pack#usage). 46 | 47 | ## License 48 | 49 | MIT [http://tameraydin.mit-license.org/](http://tameraydin.mit-license.org/) 50 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ng-inline-edit", 3 | "description": "Simple inline editing for HTML elements", 4 | "version": "0.7.0", 5 | "main": [ 6 | "dist/ng-inline-edit.js", 7 | "dist/ng-inline-edit.css" 8 | ], 9 | "keywords": [ 10 | "angular", 11 | "component", 12 | "inline-edit", 13 | "click-to-edit", 14 | "edit-in-place", 15 | "editable", 16 | "text", 17 | "title" 18 | ], 19 | "repository": { 20 | "type": "git", 21 | "url": "git://github.com/tameraydin/ng-inline-edit.git" 22 | }, 23 | "homepage": "http://tamerayd.in/ng-inline-edit", 24 | "authors": [ 25 | { 26 | "name": "Tamer Aydin", 27 | "homepage": "http://tamerayd.in" 28 | } 29 | ], 30 | "license": "MIT", 31 | "dependencies": { 32 | "angular": ">=1.3 <1.6" 33 | }, 34 | "ignore": [ 35 | "**/.*", 36 | "node_modules", 37 | "test", 38 | "src", 39 | "demo", 40 | ".travis.yml", 41 | ".editorconfig", 42 | ".gitignore", 43 | "gulpfile.js", 44 | "package.json" 45 | ], 46 | "devDependencies": { 47 | "angular-mocks": "~1.4.7", 48 | "angular-material": "~0.11.4", 49 | "angular-animate": "~1.4.7", 50 | "angular-material-icons": "~0.6.0" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /demo/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tameraydin/ng-inline-edit/b4721513c33302f6da1d4e677990b361e0d9eef7/demo/ajax-loader.gif -------------------------------------------------------------------------------- /demo/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: sans-serif; 3 | background: #f0f0f0 !important; 4 | } 5 | 6 | pre { 7 | margin: 0 !important; 8 | padding: 20px !important; 9 | } 10 | 11 | *, *:before, *:after { 12 | box-sizing: border-box; 13 | } 14 | 15 | md-content { 16 | padding: 20px; 17 | } 18 | 19 | md-tabs md-content.md-default-theme { 20 | padding: 0; 21 | } 22 | 23 | md-toolbar { 24 | margin-top: 30px; 25 | } 26 | 27 | .app-wrapper { 28 | background: #f0f0f0; 29 | padding-bottom: 30px; 30 | } 31 | 32 | .demo-wrapper { 33 | position: relative; 34 | width: 600px; 35 | margin: 0 auto; 36 | } 37 | 38 | .demo-wrapper md-tabs:last-child { 39 | margin-top: 30px; 40 | } 41 | 42 | .fade-in, 43 | .fade-out { 44 | -webkit-transition: opacity cubic-bezier(0.250, 0.460, 0.450, 0.940) .3s; 45 | -moz-transition: opacity cubic-bezier(0.250, 0.460, 0.450, 0.940) .3s; 46 | transition: opacity cubic-bezier(0.250, 0.460, 0.450, 0.940) .3s; 47 | } 48 | 49 | .fade-in.ng-hide-remove, 50 | .fade-out.ng-hide-add.ng-hide-add-active { 51 | opacity: 0; 52 | display: block !important; 53 | } 54 | 55 | .fade-out.ng-hide-add, 56 | .fade-in.ng-hide-remove.ng-hide-remove-active { 57 | opacity: 1; 58 | display: block !important; 59 | } 60 | 61 | .ng-inline-edit, 62 | .ng-inline-edit__input { 63 | font-size: 1em; 64 | } 65 | 66 | /* example-1 */ 67 | .example-1 .ng-inline-edit__input { 68 | border-bottom: 1px dashed #333; 69 | } 70 | 71 | .example-1 .ng-inline-edit--error .ng-inline-edit__input { 72 | border-color: #ff0000; 73 | } 74 | 75 | .example-1 .ng-inline-edit__button { 76 | color: blue; 77 | margin-left: 5px; 78 | } 79 | 80 | .example-1 .ng-inline-edit__button:hover { 81 | text-decoration: underline; 82 | } 83 | 84 | /* example-2 */ 85 | .example-2 .ng-inline-edit__text { 86 | padding: 2px 3px; 87 | font-weight: bold; 88 | } 89 | 90 | .example-2 .ng-inline-edit__text:hover { 91 | background: #ff0; 92 | border-radius: 4px; 93 | } 94 | 95 | .example-2 .ng-inline-edit__text--placeholder { 96 | color: #999; 97 | font-weight: normal; 98 | font-style: italic; 99 | } 100 | 101 | .example-2 .ng-inline-edit__input { 102 | padding: 0 3px; 103 | } 104 | 105 | /* example-3 */ 106 | .example-3 .ng-inline-edit__input { 107 | border: 1px solid #000; 108 | } 109 | 110 | .example-3 .ng-inline-edit--validating:after { 111 | content: ""; 112 | display: inline-block; 113 | width: 16px; 114 | height: 16px; 115 | background: url(ajax-loader.gif); 116 | } 117 | 118 | .example-3 .ng-inline-edit--validating .ng-inline-edit__input { 119 | background: #fff; 120 | opacity: .4; 121 | } 122 | 123 | .example-3 .ng-inline-edit--error .ng-inline-edit__input { 124 | color: #f00; 125 | } 126 | 127 | .example-3 .ng-inline-edit__button { 128 | font-size: 0; 129 | margin-left: 5px; 130 | visibility: hidden; 131 | opacity: .6; 132 | } 133 | 134 | .example-3 .ng-inline-edit__button:hover { 135 | opacity: 1; 136 | } 137 | 138 | .example-3 .ng-inline-edit:hover .ng-inline-edit__button, 139 | .example-3 .ng-inline-edit .ng-inline-edit__button--save, 140 | .example-3 .ng-inline-edit .ng-inline-edit__button--cancel { 141 | visibility: visible; 142 | } 143 | 144 | .example-3 .ng-inline-edit__button:after { 145 | font-size: 24px; 146 | line-height: 24px; 147 | } 148 | 149 | .example-3 .ng-inline-edit__button--edit:after { 150 | content: "\270E"; 151 | color: #00f; 152 | } 153 | 154 | .example-3 .ng-inline-edit__button--save:after { 155 | content: "\2714"; 156 | color: #0f0; 157 | } 158 | 159 | .example-3 .ng-inline-edit__button--cancel:after { 160 | content: "\2716"; 161 | color: #f00; 162 | } 163 | -------------------------------------------------------------------------------- /demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | ng-inline-edit 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 |
34 |
35 | 36 |
37 |

38 | Plain example 39 |

40 | 41 | 42 | Source 43 | 44 |
45 |
46 | 47 | 51 | 52 | 53 | 54 | HTML 55 | 56 | 57 |
<span
 58 |   inline-edit="myModel"
 59 |   inline-edit-validation="myValidator(newValue)"
 60 |   inline-edit-on-blur="cancel"></span>
61 |
62 |
63 |
64 | 65 | JS 66 | 67 |
$scope.myModel = 'An editable text';
 68 | $scope.myValidator = function(newValue) {
 69 |   // a simple required field:
 70 |   return !!newValue;
 71 | };
72 |
73 |
74 | 75 | CSS 76 | 77 |
.ng-inline-edit__input {
 78 |   border-bottom: 1px dashed #333;
 79 | }
 80 | 
 81 | .ng-inline-edit--error .ng-inline-edit__input {
 82 |   border-color: #f00;
 83 | }
 84 | 
 85 | .ng-inline-edit__button {
 86 |   color: #00f;
 87 |   margin-left: 5px;
 88 | }
 89 | 
 90 | .ng-inline-edit__button:hover {
 91 |   text-decoration: underline;
 92 | }
93 |
94 |
95 |
96 | 97 |
98 |

99 | Without button 100 |

101 | 102 | 103 | Source 104 | 105 |
106 |
107 | 108 | 115 | 116 | 117 | 118 | HTML 119 | 120 | 121 |
<span
122 |   inline-edit="myModel"
123 |   inline-edit-callback="myUpdateHandler(newValue)"
124 |   inline-edit-placeholder="Type your value here"
125 |   inline-edit-btn-edit=""
126 |   inline-edit-on-blur="save"
127 |   inline-edit-on-click></span>
128 |
129 |
130 |
131 | 132 | JS 133 | 134 |
$scope.myModel = 'Click here and delete me';
135 | $scope.myUpdateHandler = function(newValue) {
136 |   // check your console
137 |   console.log('value of your model is now: ' + newValue);
138 | };
139 |
140 |
141 | 142 | CSS 143 | 144 |
.ng-inline-edit__input {
145 |   padding: 0 3px;
146 | }
147 | 
148 | .ng-inline-edit__text {
149 |   padding: 2px 3px;
150 |   font-weight: bold;
151 | }
152 | 
153 | .ng-inline-edit__text:hover {
154 |   background: #ff0;
155 |   border-radius: 4px;
156 | }
157 | 
158 | .ng-inline-edit__text--placeholder {
159 |   color: #999;
160 |   font-weight: normal;
161 |   font-style: italic;
162 | }
163 |
164 |
165 |
166 | 167 |
168 |

169 | Server validation 170 |

171 | 172 | 173 | Source 174 | 175 |
176 |
177 | 178 | 184 | 185 | 186 | 187 | HTML 188 | 189 | 190 |
<span
191 |   inline-edit="myModel"
192 |   inline-edit-validation="validateOnServer(newValue)"
193 |   inline-edit-btn-save="Save"
194 |   inline-edit-btn-cancel="Cancel"></span>
195 |
196 |
197 |
198 | 199 | JS 200 | 201 |
$scope.myModel = 'Need more than 10 chars',
202 | $scope.validateOnServer = function(newValue) {
203 |   var defer = $q.defer();
204 | 
205 |   // a fake server validation:
206 |   $timeout(function() {
207 |     if (newValue.length > 10) { // should be more than 10 chars
208 |       defer.resolve();
209 |     } else {
210 |       defer.reject();
211 |     }
212 |   }, 2500);
213 | 
214 |   return defer.promise;
215 | };
216 |
217 |
218 | 219 | CSS 220 | 221 |
.ng-inline-edit--validating:after {
222 |   content: "";
223 |   display: inline-block;
224 |   width: 16px;
225 |   height: 16px;
226 |   background: url(ajax-loader.gif);
227 | }
228 | 
229 | .ng-inline-edit--validating .ng-inline-edit__input {
230 |   background: #fff;
231 |   opacity: .4;
232 | }
233 | 
234 | .ng-inline-edit--error .ng-inline-edit__input {
235 |   color: #f00;
236 | }
237 | 
238 | .ng-inline-edit__button {
239 |   font-size: 0;
240 |   margin-left: 5px;
241 |   visibility: hidden;
242 |   opacity: .6;
243 | }
244 | 
245 | .ng-inline-edit__button:hover {
246 |   opacity: 1;
247 | }
248 | 
249 | .ng-inline-edit:hover .ng-inline-edit__button,
250 | .ng-inline-edit .ng-inline-edit__button--save,
251 | .ng-inline-edit .ng-inline-edit__button--cancel {
252 |   visibility: visible;
253 | }
254 | 
255 | .ng-inline-edit__button:after {
256 |   font-size: 24px;
257 |   line-height: 24px;
258 | }
259 | 
260 | .ng-inline-edit__button--edit:after {
261 |   content: "\270E";
262 |   color: #00f;
263 | }
264 | 
265 | .ng-inline-edit__button--save:after {
266 |   content: "\2714";
267 |   color: #0f0;
268 | }
269 | 
270 | .ng-inline-edit__button--cancel:after {
271 |   content: "\2716";
272 |   color: #f00;
273 | }
274 |
275 |
276 |
277 | 278 |
279 |

280 | Filter example 281 |

282 | 283 | 284 | Source 285 | 286 |
287 |
288 | 289 | 295 | 296 | 297 | 298 | HTML 299 | 300 | 301 |
<span
302 | inline-edit="myModel"
303 | inline-edit-validation="myValidator(newValue)"
304 | inline-edit-filter="currency"
305 | inline-edit-on-blur="cancel"></span>
306 |
307 |
308 |
309 | 310 | JS 311 | 312 |
$scope.myModel = 1250000;
313 | $scope.myValidator = function(newValue) {
314 |   return !isNaN(newValue);
315 | };
316 |
317 |
318 | 319 | CSS 320 | 321 |
.ng-inline-edit__input {
322 |   border-bottom: 1px dashed #333;
323 | }
324 | 
325 | .ng-inline-edit--error .ng-inline-edit__input {
326 |   border-color: #f00;
327 | }
328 | 
329 | .ng-inline-edit__button {
330 |   color: #00f;
331 |   margin-left: 5px;
332 | }
333 |
334 |
335 |
336 |
337 |
338 | 339 | 340 | -------------------------------------------------------------------------------- /demo/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular 4 | .module('demoApp', [ 5 | 'ngAnimate', 6 | 'ngMaterial', 7 | 'ngMdIcons', 8 | 'angularInlineEdit' 9 | ]) 10 | .config(function($mdThemingProvider) { 11 | $mdThemingProvider.theme('default') 12 | .primaryPalette('blue') 13 | .accentPalette('red'); 14 | }) 15 | .controller('demoMainController', function($scope, $timeout, $q) { 16 | $scope.tabData = [{ 17 | selectedIndex: 0 18 | }, { 19 | selectedIndex: 0 20 | }, { 21 | selectedIndex: 0 22 | }]; 23 | 24 | $scope.examples = [{ 25 | model: 'An editable text', 26 | validator: function(newValue) { 27 | return !!newValue; 28 | } 29 | }, { 30 | model: 'Click here and delete me', 31 | placeholder: 'Type your value here', 32 | callback: function(newValue) { 33 | console.log('value of your model is now: ' + newValue); 34 | } 35 | }, { 36 | model: 'Need more than 10 chars', 37 | validator: function(newValue) { 38 | var defer = $q.defer(); 39 | 40 | $timeout(function() { 41 | if (newValue.length > 10) { 42 | defer.resolve(); 43 | } else { 44 | defer.reject(); 45 | } 46 | }, 2500); 47 | 48 | return defer.promise; 49 | } 50 | }, { 51 | model: '1250000', 52 | validator: function(newValue) { 53 | return !isNaN(newValue); 54 | } 55 | }]; 56 | }); 57 | -------------------------------------------------------------------------------- /dist/ng-inline-edit.css: -------------------------------------------------------------------------------- 1 | /** 2 | * ng-inline-edit v0.7.0 (http://tamerayd.in/ng-inline-edit) 3 | * Copyright 2015 Tamer Aydin (http://tamerayd.in) 4 | * Licensed under MIT 5 | */ 6 | .ng-inline-edit__input { 7 | border: 0; 8 | outline: 0; 9 | display: inline-block; 10 | -webkit-appearance: none; 11 | -moz-appearance: none; } 12 | .ng-inline-edit__inner-container { 13 | display: inline-block; } 14 | .ng-inline-edit__button { 15 | cursor: pointer; } 16 | -------------------------------------------------------------------------------- /dist/ng-inline-edit.js: -------------------------------------------------------------------------------- 1 | /** 2 | * ng-inline-edit v0.7.0 (http://tamerayd.in/ng-inline-edit) 3 | * Copyright 2015 Tamer Aydin (http://tamerayd.in) 4 | * Licensed under MIT 5 | */ 6 | (function(window, angular, undefined) { 7 | 'use strict'; 8 | 9 | angular 10 | .module('angularInlineEdit.providers', []) 11 | .value('InlineEditConfig', { 12 | btnEdit: 'Edit', 13 | btnSave: '', 14 | btnCancel: '', 15 | editOnClick: false, 16 | onBlur: null 17 | }) 18 | .constant('InlineEditConstants', { 19 | CANCEL: 'cancel', 20 | SAVE: 'save' 21 | }); 22 | 23 | })(window, window.angular); 24 | 25 | (function(window, angular, undefined) { 26 | 'use strict'; 27 | 28 | angular 29 | .module('angularInlineEdit.controllers', []) 30 | .controller('InlineEditController', ['$scope', '$document', '$timeout', 31 | function($scope, $document, $timeout) { 32 | $scope.placeholder = ''; 33 | $scope.validationError = false; 34 | $scope.validating = false; 35 | $scope.isOnBlurBehaviorValid = false; 36 | $scope.cancelOnBlur = false; 37 | $scope.editMode = false; 38 | $scope.inputValue = ''; 39 | 40 | $scope.editText = function(inputValue) { 41 | $scope.editMode = true; 42 | $scope.inputValue = (typeof inputValue === 'string') ? 43 | inputValue : $scope.model; 44 | 45 | $timeout(function() { 46 | $scope.editInput[0].focus(); 47 | if ($scope.isOnBlurBehaviorValid) { 48 | $document.bind('click', $scope.onDocumentClick); 49 | } 50 | }, 0); 51 | }; 52 | 53 | $scope.applyText = function(cancel, byDOM) { 54 | var inputValue = $scope.inputValue; // initial input value 55 | $scope.validationError = false; 56 | 57 | function _onSuccess() { 58 | $scope.model = inputValue; 59 | $scope.callback({ 60 | newValue: inputValue 61 | }); 62 | 63 | $scope.editMode = false; 64 | } 65 | 66 | function _onFailure() { 67 | $scope.validationError = true; 68 | $timeout(function() { 69 | $scope.editText(inputValue); 70 | }, 0); 71 | } 72 | 73 | function _onEnd(apply) { 74 | $scope.validating = false; 75 | if (apply && byDOM) { 76 | $scope.$apply(); 77 | } 78 | } 79 | 80 | if (cancel || $scope.model === inputValue) { 81 | $scope.editMode = false; 82 | if (byDOM) { 83 | $scope.$apply(); 84 | } 85 | 86 | } else { 87 | $scope.validating = true; 88 | if (byDOM) { 89 | $scope.$apply(); 90 | } 91 | 92 | var validationResult = $scope.validate({ 93 | newValue: $scope.inputValue 94 | }); 95 | 96 | if (validationResult && validationResult.then) { // promise 97 | validationResult 98 | .then(_onSuccess) 99 | .catch(_onFailure) 100 | .finally(_onEnd); 101 | 102 | } else if (validationResult || 103 | typeof validationResult === 'undefined') { 104 | _onSuccess(); 105 | _onEnd(true); 106 | 107 | } else { 108 | _onFailure(); 109 | _onEnd(true); 110 | } 111 | } 112 | 113 | if ($scope.isOnBlurBehaviorValid) { 114 | $document.unbind('click', $scope.onDocumentClick); 115 | } 116 | }; 117 | 118 | $scope.onInputKeyup = function(event) { 119 | if (!$scope.validating) { 120 | switch (event.keyCode) { 121 | case 13: // ENTER 122 | if ($scope.isInputTextarea) { 123 | return; 124 | } 125 | $scope.applyText(false, false); 126 | break; 127 | case 27: // ESC 128 | $scope.applyText(true, false); 129 | break; 130 | default: 131 | break; 132 | } 133 | } 134 | }; 135 | 136 | $scope.onDocumentClick = function(event) { 137 | if (!$scope.validating) { 138 | if (event.target !== $scope.editInput[0]) { 139 | $scope.applyText($scope.cancelOnBlur, true); 140 | } 141 | } 142 | }; 143 | } 144 | ]); 145 | 146 | })(window, window.angular); 147 | 148 | (function(window, angular, undefined) { 149 | 'use strict'; 150 | 151 | angular 152 | .module('angularInlineEdit.directives', [ 153 | 'angularInlineEdit.providers', 154 | 'angularInlineEdit.controllers' 155 | ]) 156 | .directive('inlineEdit', ['$compile', 'InlineEditConfig', 'InlineEditConstants', 157 | function($compile, InlineEditConfig, InlineEditConstants) { 158 | return { 159 | restrict: 'A', 160 | controller: 'InlineEditController', 161 | scope: { 162 | model: '=inlineEdit', 163 | callback: '&inlineEditCallback', 164 | validate: '&inlineEditValidation' 165 | }, 166 | link: function(scope, element, attrs) { 167 | scope.model = scope.$parent.$eval(attrs.inlineEdit); 168 | scope.isInputTextarea = attrs.hasOwnProperty('inlineEditTextarea'); 169 | 170 | var onBlurBehavior = attrs.hasOwnProperty('inlineEditOnBlur') ? 171 | attrs.inlineEditOnBlur : InlineEditConfig.onBlur; 172 | if (onBlurBehavior === InlineEditConstants.CANCEL || 173 | onBlurBehavior === InlineEditConstants.SAVE) { 174 | scope.isOnBlurBehaviorValid = true; 175 | scope.cancelOnBlur = onBlurBehavior === InlineEditConstants.CANCEL; 176 | } 177 | 178 | var container = angular.element( 179 | '
'); 182 | 183 | var input = angular.element( 184 | (scope.isInputTextarea ? 185 | '