PageSourceSearch

https://www.h-j.com/DesktopModules/MVC/SteadyRain/ProductCatalog.W…/js/libs/knockout-extension.js?cdv=986

js h-j.com collected 2026-10-06 04:42:56 UTC 11,141 bytes, 269 lines download raw bytes

1//referenced from this link: http://www.aaronkjackson.com/2012/04/formatting-dates-with-knockoutjs/
2ko.bindingHandlers.dateString = {
3    update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
4        var value = valueAccessor();
5        var allBindings = allBindingsAccessor();
6        var valueUnwrapped = ko.utils.unwrapObservable(value);
7
8        var dateUnwrapped = new Date(valueUnwrapped);
9        valueUnwrapped = moment(dateUnwrapped).toISOString();
10
11        var pattern = allBindings.datePattern || 'MM/dd/yyyy';
12        //allBindings.value(moment(valueUnwrapped).format(pattern));        //Under some condition, allBindings.value would be undefined.
13        if (valueUnwrapped !== null && valueUnwrapped !== undefined && valueUnwrapped.length > 0 && valueUnwrapped !== "Invalid date") {
14            $(element).val(moment(valueUnwrapped).format(pattern));
15        }
16        //Remove the "else" since we allow user to type date in text field.
17    }
18};
19
20ko.bindingHandlers.datetimePicker = {
21    init: function (element, valueAccessor) {
22        var value = valueAccessor();
23        $(element).datetimepicker({
24            format: 'mm/dd/yyyy',
25            weekStart: 1,
26            todayBtn: 'linked',
27            autoclose: true,
28            todayHighlight: 1,
29            startView: 2,
30            minView: 2,
31            forceParse: 0,
32            bootcssVer: 3
33        }).on('changeDate', function (ev) {
34            value(ev.date);
35        });
36    },
37    update: function (element, valueAccessor) {
38        var value = valueAccessor();
39        $(element).val(new Date(ko.unwrap(value)).format('MM/dd/yyyy'));
40    }
41};
42
43ko.bindingHandlers.tagsInput = {
44    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
45        var value = valueAccessor()
46        var options = allBindingsAccessor();
47        options = Object.assign({}, {
48            freeInput: false,
49            param: "",
50            itemText: function (item) {
51                return item.Name;
52            },
53            itemValue: function (item) {
54                return item.Id;
55            }
56        }, options);
57
58        $(element).tagsinput({
59            freeInput: options.freeInput,
60            confirmKeys: [13, 44, 59],
61            itemText: options.itemText,
62            itemValue: options.itemValue,
63            trimValue: true,
64            typeahead: {
65                items: 5,
66                source: typeof options.sourceHandler === 'function' ? options.sourceHandler :
67                    typeof options.sourceHandler === 'string' ? function (query) {
68                        return $.stormstorecrud($.stormstoreservice('/' + options.sourceHandler, 'QueryByName'), 'GET', String.format("query={0}{1}", query, options.param));
69                    } :
70                        options.sourceHandler instanceof Array ? options.sourceHandler : []
71            }
72        });
73
74        var handler = function (event) { value($(event.target).tagsinput('items')); };
75        $(element).on('itemAdded', handler).on('itemRemoved', handler);
76
77        (ko.toJS(value) || []).forEach(function (item) {
78            $(element).tagsinput("add", item);
79        });
80    }
81};
82
83//http://knockoutjs.com/documentation/fn.html
84//This method is to filter the current array with specified value.
85ko.observableArray.fn.filterByProperty = function (propName, matchValue) {
86
87    return ko.pureComputed(function () {
88
89        var allItems = this(),
90            matchingItems = [];
91
92        for (var i = 0; i < allItems.length; i++) {
93            var current = allItems[i];
94            if (ko.unwrap(current[propName]) === matchValue)
95                matchingItems.push(current);
96        }
97
98        return matchingItems;
99    }, this);
100}
101
102
103ko.extenders.numeric = function (target, precision) {
104    //create a writable computed observable to intercept writes to our observable
105    var result = ko.pureComputed({
106        read: target,  //always return the original observables value
107        write: function (newValue) {
108            var current = target(),
109                roundingMultiplier = Math.pow(10, precision),
110                newValueAsNum = isNaN(newValue) ? 0 : +newValue,
111                valueToWrite = Math.round(newValueAsNum * roundingMultiplier) / roundingMultiplier;
112
113            //only write if it changed
114            if (valueToWrite !== current) {
115                target(valueToWrite);
116            } else {
117                //if the rounded value is the same, but a different value was written, force a notification for the current field
118                if (newValue !== current) {
119                    target.notifySubscribers(valueToWrite);
120                }
121            }
122        }
123    }).extend({ notify: 'always' });
124
125    //initialize with current value to make sure it is rounded appropriately
126    result(target());
127
128    //return the new computed observable
129    return result;
130};
131
132ko.extenders.range = function (target, intRange) {
133    //create a writeable computed observable to intercept writes to our observable
134    var result = ko.computed({
135        read: target,  //always return the original observables value
136        write: function (newValue) {
137            var current = target(),
138                newValueAsNum = isNaN(newValue) ? 0 : parseInt(+newValue, 10),
139                valueToWrite = newValueAsNum;
140
141            if (newValueAsNum < intRange.min) {
142                valueToWrite = intRange.min;
143            }
144
145            if (newValueAsNum > intRange.max) {
146                valueToWrite = intRange.max;
147            }
148            //only write if it changed
149            if (valueToWrite !== current) {
150                target(valueToWrite);
151            } else {
152                //if the tested value is the same, but a different value was written, force a notification for the current field
153                if (newValue !== current) {
154                    target.notifySubscribers(valueToWrite);
155                }
156            }
157        }
158    }).extend({ notify: 'always' });
159
160    //initialize with current value to make sure it is rounded appropriately
161    result(target());
162
163    //return the new computed observable
164    return result;
165};
166ko.bindingHandlers.masked = {
167    init: function (element, valueAccessor, allBindingsAccessor) {
168        var mask = allBindingsAccessor().mask || {};
169        $(element).mask(mask, { placeholder: mask });
170        ko.utils.registerEventHandler(element, 'focusout', function () {
171            var observable = valueAccessor();
172            observable($(element).cleanVal());
173        });
174    },
175    update: function (element, valueAccessor) {
176        var value = ko.utils.unwrapObservable(valueAccessor());
177        $(element).val($(element).masked(value));
178    }
179};
180// From StackOverflow: https://stackoverflow.com/questions/47203657/select2-4-x-and-knockoutjs
181ko.bindingHandlers.select2 = {
182    init: function (el, valueAccessor, allBindingsAccessor, viewModel) {
183        ko.utils.domNodeDisposal.addDisposeCallback(el, function () {
184            $(el).select2('destroy');
185        });
186
187        var allBindings = allBindingsAccessor(),
188            select2 = ko.utils.unwrapObservable(allBindings.select2);
189        if (select2.remote) {
190            $(el).append('<option value></option>');
191            $(el).select2({
192                ajax: {
193                    url: globalConfig.baseUrl + select2.url,
194                    dataType: 'json',
195                    delay: 250,
196                    data: function (params) {
197                        var parameters = {
198                            query: params.term || '' // search term                            
199                        };
200
201                        if (select2.params !== undefined) {
202                            $.each(Object.keys(select2.params), function (index, value) {
203                                parameters[value] = select2.params[value]();
204                            })
205                        }
206                        return parameters;
207                    },
208                    processResults: function (data, params) {
209
210                        // parse the results into the format expected by Select2
211                        // since we are using custom formatting functions we do not need to
212                        // alter the remote JSON data, except to indicate that infinite
213                        // scrolling can be used
214                        params.page = params.page || 1;
215                        var result = [];
216                        $.each(data, function (index, value) {
217                            result.push({ id: value.Id, text: value.Name })
218                        })
219                        return {
220                            results: result,
221                            //pagination: {
222                            // more: (params.page * 30) < data.total_count
223                            //}
224                        };
225                    },
226                    cache: true
227                },
228                escapeMarkup: function (markup) { return markup; }, // let our custom formatter work              
229                placeholder: select2.placeholder,
230                allowClear: select2.allowClear
231            });
232        }
233        else {
234            $(el).select2(select2);
235        }
236    },
237    update: function (el, valueAccessor, allBindingsAccessor, viewModel) {
238        var allBindings = allBindingsAccessor();
239        if ("value" in allBindings) {
240            if ((allBindings.select2.multiple || el.multiple) && allBindings.value(
240) && allBindings.value().constructor != Array) {
241                $(el).val(allBindings.value().split(',')).trigger('change');
242            }
243            else {
244                $(el).val(allBindings.value()).trigger('change');
245            }
246        } else if ("selectedOptions" in allBindings) {
247            var converted = [];
248            var textAccessor = function (value) { return value; };
249            if ("optionsText" in allBindings) {
250                textAccessor = function (value) {
251                    var valueAccessor = function (item) { return item; }
252                    if ("optionsValue" in allBindings) {
253                        valueAccessor = function (item) { return item[allBindings.optionsValue]; }
254                    }
255                    var items = $.grep(allBindings.options(), function (e) { return valueAccessor(e) == value });
256                    if (items.length == 0 || items.length > 1) {
257                        return "UNKNOWN";
258                    }
259                    return items[0][allBindings.optionsText];
260                }
261            }
262            $.each(allBindings.selectedOptions(), function (key, value) {
263                converted.push({ id: value, text: textAccessor(value) });
264            });
265            $(el).select2("data", converted);
266        }
267        $(el).trigger("change");
268    }
269};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.