Skip to content

Commit 347be5a

Browse files
committed
fixed select with ng:format
select (one/multiple) could not chose from a list of objects, since DOM requires string ids. Solved by adding index formatter, which exposed incorrect handling of formatters in select widgets.
1 parent 934f44f commit 347be5a

13 files changed

Lines changed: 433 additions & 171 deletions

CHANGELOG.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# <angular/> 0.9.10 flea-whisperer (in-progress) #
22

3+
### Bug Fixes
4+
- html select (one/multiple) could not chose from a list of objects, since DOM requires string ids.
35

46

57
# <angular/> 0.9.9 time-shift (2011-01-13) #
@@ -99,9 +101,9 @@
99101
- small docs improvements (mainly docs for the $resource service)
100102

101103
### Breaking changes
102-
- Angular expressions in the view used to support regular expressions. This feature was rarely
103-
used and added unnecessary complexity. It not a good idea to have regexps in the view anyway,
104-
so we removed this support. If you had any regexp in your views, you will have to move them to
104+
- Angular expressions in the view used to support regular expressions. This feature was rarely
105+
used and added unnecessary complexity. It not a good idea to have regexps in the view anyway,
106+
so we removed this support. If you had any regexp in your views, you will have to move them to
105107
your controllers. (commit e5e69d9b90850eb653883f52c76e28dd870ee067)
106108

107109

@@ -120,7 +122,7 @@
120122
- docs app UI polishing with dual scrolling and other improvements
121123

122124
### Bug Fixes
123-
- `select` widget now behaves correctly when it's `option` items are created via `ng:repeat`
125+
- `select` widget now behaves correctly when it's `option` items are created via `ng:repeat`
124126
(issue #170)
125127
- fix for async xhr cache issue #152 by adding `$browser.defer` and `$defer` service
126128

docs/spec/ngdocSpec.js

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
var ngdoc = require('ngdoc.js');
2+
var DOM = require('dom.js').DOM;
23

34
describe('ngdoc', function(){
45
var Doc = ngdoc.Doc;
@@ -253,5 +254,67 @@ describe('ngdoc', function(){
253254
});
254255
});
255256
});
257+
258+
describe('usage', function(){
259+
var dom;
260+
261+
beforeEach(function(){
262+
dom = new DOM();
263+
this.addMatchers({
264+
toContain: function(text) {
265+
this.actual = this.actual.toString();
266+
return this.actual.indexOf(text) > -1;
267+
}
268+
});
269+
});
270+
271+
describe('filter', function(){
272+
it('should format', function(){
273+
var doc = new Doc({
274+
ngdoc:'formatter',
275+
shortName:'myFilter',
276+
param: [
277+
{name:'a'},
278+
{name:'b'}
279+
]
280+
});
281+
doc.html_usage_filter(dom);
282+
expect(dom).toContain('myFilter_expression | myFilter:b');
283+
expect(dom).toContain('angular.filter.myFilter(a, b)');
284+
});
285+
});
286+
287+
describe('validator', function(){
288+
it('should format', function(){
289+
var doc = new Doc({
290+
ngdoc:'validator',
291+
shortName:'myValidator',
292+
param: [
293+
{name:'a'},
294+
{name:'b'}
295+
]
296+
});
297+
doc.html_usage_validator(dom);
298+
expect(dom).toContain('ng:validate="myValidator:b"');
299+
expect(dom).toContain('angular.validator.myValidator(a, b)');
300+
});
301+
});
302+
303+
describe('formatter', function(){
304+
it('should format', function(){
305+
var doc = new Doc({
306+
ngdoc:'formatter',
307+
shortName:'myFormatter',
308+
param: [
309+
{name:'a'},
310+
]
311+
});
312+
doc.html_usage_formatter(dom);
313+
expect(dom).toContain('ng:format="myFormatter:a"');
314+
expect(dom).toContain('var userInputString = angular.formatter.myFormatter.format(modelValue, a);');
315+
expect(dom).toContain('var modelValue = angular.formatter.myFormatter.parse(userInputString, a);');
316+
});
317+
});
318+
});
256319

257320
});

docs/src/ngdoc.js

Lines changed: 37 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -231,15 +231,7 @@ Doc.prototype = {
231231
dom.code(function(){
232232
dom.text(self.name);
233233
dom.text('(');
234-
var first = true;
235-
(self.param || []).forEach(function(param){
236-
if (first) {
237-
first = false;
238-
} else {
239-
dom.text(', ');
240-
}
241-
dom.text(param.name);
242-
});
234+
self.parameters(dom, ', ');
243235
dom.text(');');
244236
});
245237

@@ -273,44 +265,17 @@ Doc.prototype = {
273265
dom.text(self.shortName);
274266
dom.text('_expression | ');
275267
dom.text(self.shortName);
276-
var first = true;
277-
(self.param||[]).forEach(function(param){
278-
if (first) {
279-
first = false;
280-
} else {
281-
if (param.optional) {
282-
dom.tag('i', function(){
283-
dom.text('[:' + param.name + ']');
284-
});
285-
} else {
286-
dom.text(':' + param.name);
287-
}
288-
}
289-
});
268+
self.parameters(dom, ':', true);
290269
dom.text(' }}');
291270
});
292271
});
293272

294-
dom.h3('In JavaScript', function(){
273+
dom.h('In JavaScript', function(){
295274
dom.tag('code', function(){
296275
dom.text('angular.filter.');
297276
dom.text(self.shortName);
298277
dom.text('(');
299-
var first = true;
300-
(self.param||[]).forEach(function(param){
301-
if (first) {
302-
first = false;
303-
dom.text(param.name);
304-
} else {
305-
if (param.optional) {
306-
dom.tag('i', function(){
307-
dom.text('[, ' + param.name + ']');
308-
});
309-
} else {
310-
dom.text(', ' + param.name);
311-
}
312-
}
313-
});
278+
self.parameters(dom, ', ');
314279
dom.text(')');
315280
});
316281
});
@@ -319,32 +284,40 @@ Doc.prototype = {
319284
self.html_usage_returns(dom);
320285
});
321286
},
322-
287+
323288
html_usage_formatter: function(dom){
324289
var self = this;
325290
dom.h('Usage', function(){
326291
dom.h('In HTML Template Binding', function(){
327292
dom.code(function(){
328-
dom.text('<input type="text" ng:format="');
293+
if (self.inputType=='select')
294+
dom.text('<select name="bindExpression"');
295+
else
296+
dom.text('<input type="text" name="bindExpression"');
297+
dom.text(' ng:format="');
329298
dom.text(self.shortName);
299+
self.parameters(dom, ':', false, true);
330300
dom.text('">');
331301
});
332302
});
333303

334-
dom.h3('In JavaScript', function(){
304+
dom.h('In JavaScript', function(){
335305
dom.code(function(){
336306
dom.text('var userInputString = angular.formatter.');
337307
dom.text(self.shortName);
338-
dom.text('.format(modelValue);');
339-
});
340-
dom.html('<br/>');
341-
dom.code(function(){
308+
dom.text('.format(modelValue');
309+
self.parameters(dom, ', ', false, true);
310+
dom.text(');');
311+
dom.text('\n');
342312
dom.text('var modelValue = angular.formatter.');
343313
dom.text(self.shortName);
344-
dom.text('.parse(userInputString);');
314+
dom.text('.parse(userInputString');
315+
self.parameters(dom, ', ', false, true);
316+
dom.text(');');
345317
});
346318
});
347319

320+
self.html_usage_parameters(dom);
348321
self.html_usage_returns(dom);
349322
});
350323
},
@@ -356,18 +329,7 @@ Doc.prototype = {
356329
dom.code(function(){
357330
dom.text('<input type="text" ng:validate="');
358331
dom.text(self.shortName);
359-
var first = true;
360-
(self.param||[]).forEach(function(param){
361-
if (first) {
362-
first = false;
363-
} else {
364-
if (param.optional) {
365-
dom.text('[:' + param.name + ']');
366-
} else {
367-
dom.text(':' + param.name);
368-
}
369-
}
370-
});
332+
self.parameters(dom, ':', true);
371333
dom.text('"/>');
372334
});
373335
});
@@ -377,19 +339,7 @@ Doc.prototype = {
377339
dom.text('angular.validator.');
378340
dom.text(self.shortName);
379341
dom.text('(');
380-
var first = true;
381-
(self.param||[]).forEach(function(param){
382-
if (first) {
383-
first = false;
384-
dom.text(param.name);
385-
} else {
386-
if (param.optional) {
387-
dom.text('[, ' + param.name + ']');
388-
} else {
389-
dom.text(', ' + param.name);
390-
}
391-
}
392-
});
342+
self.parameters(dom, ', ');
393343
dom.text(')');
394344
});
395345
});
@@ -443,8 +393,22 @@ Doc.prototype = {
443393
},
444394

445395
html_usage_service: function(dom){
446-
}
396+
},
447397

398+
parameters: function(dom, separator, skipFirst, prefix) {
399+
var sep = prefix ? separator : '';
400+
(this.param||[]).forEach(function(param, i){
401+
if (!(skipFirst && i==0)) {
402+
if (param.optional) {
403+
dom.text('[' + sep + param.name + ']');
404+
} else {
405+
dom.text(sep + param.name);
406+
}
407+
}
408+
sep = separator;
409+
});
410+
}
411+
448412
};
449413
//////////////////////////////////////////////////////////
450414

src/JSON.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ function toJson(obj, pretty) {
3333
* @returns {Object|Array|Date|string|number} Deserialized thingy.
3434
*/
3535
function fromJson(json, useNative) {
36-
if (!json) return json;
36+
if (!isString(json)) return json;
3737

3838
var obj, p, expression;
3939

src/directives.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ angularDirective("ng:bind", function(expression, element){
197197
if (lastValue === value && lastError == error) return;
198198
isDomElement = isElement(value);
199199
if (!isHtml && !isDomElement && isObject(value)) {
200-
value = toJson(value);
200+
value = toJson(value, true);
201201
}
202202
if (value != lastValue || error != lastError) {
203203
lastValue = value;
@@ -234,7 +234,7 @@ function compileBindTemplate(template){
234234
return text;
235235
});
236236
});
237-
bindTemplateCache[template] = fn = function(element){
237+
bindTemplateCache[template] = fn = function(element, prettyPrintJson){
238238
var parts = [], self = this,
239239
oldElement = this.hasOwnProperty($$element) ? self.$element : _undefined;
240240
self.$element = element;
@@ -243,7 +243,7 @@ function compileBindTemplate(template){
243243
if (isElement(value))
244244
value = '';
245245
else if (isObject(value))
246-
value = toJson(value, true);
246+
value = toJson(value, prettyPrintJson);
247247
parts.push(value);
248248
}
249249
self.$element = oldElement;
@@ -292,7 +292,7 @@ angularDirective("ng:bind-template", function(expression, element){
292292
return function(element) {
293293
var lastValue;
294294
this.$onEval(function() {
295-
var value = templateFn.call(this, element);
295+
var value = templateFn.call(this, element, true);
296296
if (value != lastValue) {
297297
element.text(value);
298298
lastValue = value;

0 commit comments

Comments
 (0)