constructor(fieldAccessor) { const self = this; self.entries = ko.observableArray(); self.fieldAccessor = fieldAccessor; self.filtered = ko.pureComputed(() => { let result = self.entries(); if (self.filter()) { result = sqlUtils.autocompleteFilter(self.filter(), result); huePubSub.publish('hue.ace.autocompleter.match.updated'); } sqlUtils.sortSuggestions(result, self.filter(), self.sortOverride); return result; }); self.availableCategories = ko.pureComputed(() => { // TODO: Implement autocomplete logic return [CATEGORIES.ALL]; }); self.loading = ko.observable(false); self.filter = ko.observable(); self.cancelRequests = function() {}; }
constructor (opts) { this.opts = opts; Project.columnKeys.forEach(key => { this[key] = ko.observable(opts[key]); }); // array init this.stages = ko.observableArray(); this.costs = ko.observableArray(); this.labels = ko.observableArray(); this.users = ko.observableArray(); this.tasks = ko.observableArray(); (opts.stages || []).forEach(x => this.addStage(x)); (opts.costs || []).forEach(x => this.addCost(x)); (opts.labels || []).forEach(x => this.addLabel(x)); _.reverse(opts.users || []).forEach(x => this.addUser(x)); _.reverse(opts.tasks || []).forEach(x => this.addTask(x)); // defaultValue init this.defaultStage = ko.pureComputed(() => this.stages().find(x => this.getStage({id: x.id()}))); this.defaultCost = ko.pureComputed(() => this.costs().find(x => this.getCost({id: x.id()}))); // getTasksのmemo this.memoGetTasks = {}; // url of kanban board page this.url = ko.pureComputed(() => { const username = this.createUser().username; const id = this.id(); const name = this.name(); return `/users/${username}/projects/${id}/${name}`; }); }
constructor: function(nodeTitle) { this.super.constructor.call(this); var self = this; this.nodeTitle = nodeTitle; this.submitEnabled = ko.observable(true); this.searchAllProjectsSubmitText = ko.observable(SEARCH_ALL_SUBMIT_TEXT); this.searchMyProjectsSubmitText = ko.observable(SEARCH_MY_PROJECTS_SUBMIT_TEXT); this.query = ko.observable(); this.results = ko.observableArray(); this.selection = ko.observableArray(); this.errorMsg = ko.observable(''); this.totalPages = ko.observable(0); this.includePublic = ko.observable(true); this.searchWarningMsg = ko.observable(''); this.submitWarningMsg = ko.observable(''); this.loadingResults = ko.observable(false); this.foundResults = ko.pureComputed(function() { return self.query() && self.results().length; }); this.noResults = ko.pureComputed(function() { return self.query() && !self.results().length; }); },
var Draft = function(params, metaSchema) { var self = this; self.pk = params.pk; self.schemaData = params.registration_metadata || {}; self.metaSchema = metaSchema || new MetaSchema(params.registration_schema, self.schemaData); self.schema = ko.pureComputed(function() { return self.metaSchema.schema; }); self.initiator = params.initiator; self.initiated = new Date(params.initiated); self.updated = new Date(params.updated); self.urls = params.urls || {}; self.isPendingApproval = params.is_pending_approval; self.isApproved = params.is_approved; self.requiresApproval = ko.pureComputed(function() { return self.metaSchema && self.metaSchema.requiresApproval; }); self.fulfills = ko.pureComputed(function() { return self.metaSchema ? self.metaSchema.fulfills : []; }); self.pages = ko.computed(function() { return self.metaSchema.pages; }); self.userHasUnseenComment = ko.computed(function() { return $osf.any( $.map(self.pages(), function(page) { return page.getUnseenComments().length > 0; }) ); }); self.hasRequiredQuestions = ko.pureComputed(function() { return self.metaSchema.flatQuestions().filter(function(q) { return q.required; }).length > 0; }); self.completion = ko.computed(function() { var complete = 0; var questions = self.metaSchema.flatQuestions() .filter(function(question) { return question.required; }); $.each(questions, function(_, question) { if (question.isComplete()) { complete++; } }); return Math.ceil(100 * (complete / questions.length)); }); };
constructor: function(title, parentId, parentTitle) { this.super.constructor.call(this); var self = this; self.title = title; self.parentId = parentId; self.parentTitle = parentTitle; //list of permission objects for select. self.permissionList = [ {value: 'read', text: 'Read'}, {value: 'write', text: 'Read + Write'}, {value: 'admin', text: 'Administrator'} ]; self.page = ko.observable('whom'); self.pageTitle = ko.computed(function() { return { whom: 'Add Contributors', which: 'Select Components', invite: 'Add Unregistered Contributor' }[self.page()]; }); self.query = ko.observable(); self.results = ko.observableArray([]); self.selection = ko.observableArray(); self.notification = ko.observable(''); self.inviteError = ko.observable(''); self.totalPages = ko.observable(0); self.nodes = ko.observableArray([]); self.nodesToChange = ko.observableArray(); $.getJSON( nodeApiUrl + 'get_editable_children/', {}, function(result) { $.each(result.children || [], function(idx, child) { child.margin = NODE_OFFSET + child.indent * NODE_OFFSET + 'px'; }); self.nodes(result.children); } ); self.foundResults = ko.pureComputed(function() { return self.query() && self.results().length; }); self.noResults = ko.pureComputed(function() { return self.query() && !self.results().length; }); self.inviteName = ko.observable(); self.inviteEmail = ko.observable(); self.addingSummary = ko.computed(function() { var names = $.map(self.selection(), function(result) { return result.fullname; }); return names.join(', '); }); },
constructor (data) { this.operator = ko.observable() this.value = ko.observable() this.byVariable = ko.pureComputed(() => this.value() instanceof Variable) this.byValue = ko.pureComputed(() => !this.byVariable()) this.update(data) }
constructor ({eventEmitterOptions = {}} = {}) { super({eventEmitterOptions}); this.user = ko.observable(); this.wipLimit = ko.observable(0); this.user.subscribe(user => { this.wipLimit(user.wipLimit()); }); this.canRemove = ko.pureComputed(() => this.user() && this.user().wip() === 0); this.canUpdate = ko.pureComputed(() => this.user() && this.user().wip() <= this.wipLimit()); }
/** * Create a project detail view */ constructor(params) { this.isReady = ko.observable(false) this.projects = ko.observableArray([]) this.hasProjects = ko.pureComputed(() => this.projects().length > 0) this.selectedProject = ko.observable(null) this.notifications = ko.observableArray([]) this.count = ko.observable(0) this.total = ko.observable(0) /** * Calculates this the mappings' current progress */ this.progress = ko.pureComputed(() => { return Math.ceil((this.count() / this.total()) * 100) }).extend({throttle: 1}) this.progressWidth = ko.pureComputed( () => `${this.progress()}%` ) this.isProcessing = ko.pureComputed( () => this.progress() < 100 ) this.progressStatus = ko.pureComputed(() => { return this.progress() == 100 ? 'success' : 'info' }) this.pubsub = new EventSource(STATUS_URI) this.pubsub.addEventListener('progress', event => { let data = JSON.parse(event.data) this.count(data['count']) this.total(data['total']) console.log(this.progress()) }) this.pubsub.addEventListener('message', event => { let {variable, message} = JSON.parse(event.data) console.log(message) this.notifications.push(`${variable} -- ${message}`) }) this.notifications.push('Sending request to process mappings.') Project.query() .then( projects => { this.projects(projects.filter(project => project.title() != 'DRSC')) if (this.hasProjects()){ this.selectedProject(this.projects()[0]); } }) }
var Filter = function() { var self = this; MetricRangeFilter.call(this); this.defineMinMax = false; this.displayValue = ko.pureComputed(function() { return Math.round(self.range().max * parseInt(self.inputValue())); }); this.outputValue = ko.pureComputed(function() { return self.range().max * parseInt(self.inputValue()) / 100; }); };
constructor ({eventEmitterOptions = {}, project}) { super(eventEmitterOptions); localStorage.load(); this.joinedUsers = ko.observableArray([]); this.joinedUniqueUsers = ko.pureComputed(() => _.uniq(this.joinedUsers())); this.activities = ko.observableArray(); this.searchQuery = ko.observable(); this.searchQuery.subscribe(_.debounce(this.searchTasks.bind(this), 500)); this.searchHitTaskNum = ko.observable(null); this._searchHitTaskNumFormat = ko.observable(null); this.searchHitTaskNumFormat = ko.pureComputed({ read: () => this._searchHitTaskNumFormat(), write: v => this._searchHitTaskNumFormat(v) }); this.searchHitTaskNum.subscribe((delayReset => num => { if (num === null) { this.searchHitTaskNumFormat(null); } else { this.searchHitTaskNumFormat(num ? `Hit ${num} tasks` : 'No hit task'); delayReset(); } })(_.debounce(() => this.searchHitTaskNumFormat(null), 2000))); this.viewMode = ko.observable(localStorage.getItem('viewMode')); // full or compact this.viewMode.subscribe(val => localStorage.setItem('viewMode', val)); this.project = project; this.users = project.users; this.tasks = project.tasks; this.labels = project.labels; this.stages = project.stages; this.stats = new ProjectStats({project}); this.loginUser = ko.pureComputed(() => this.users().find(user => user.username() === global.username)); this.canAssignUsers = ko.pureComputed(() => this.users().filter(user => !user.isWipLimited())); this.selectedTask = ko.observable(); this.selectedUser = ko.observable(); this.socket = null; this.socketSerializer = null; this.initSocket(); this.initModals(); }
function applyBinding(el, bindings, ctx) { const path = bindings.has('path') ? bindings.get('path') : false const query = bindings.has('query') ? bindings.get('query') : false const state = bindings.has('state') ? bindings.get('state') : false const bindingsToApply = {} el.href = '#' bindingsToApply.click = (data, e) => { const debounce = 1 !== which(e) const hasOtherTarget = el.hasAttribute('target') const hasExternalRel = el.getAttribute('rel') === 'external' const modifierKey = e.metaKey || e.ctrlKey || e.shiftKey if (debounce || hasOtherTarget || hasExternalRel || modifierKey) { return true } const [router, route] = getRoute(ctx, path) const handled = router.update(route, ko.toJS(state), true, ko.toJS(query)) if (handled) { e.preventDefault() e.stopImmediatePropagation() } else if (!router.$parent) { console.error(`[ko-component-router] ${path} did not match any routes!`) // eslint-disable-line } return !handled } bindingsToApply.attr = { href: ko.pureComputed(() => resolveHref(ctx, bindings.get('path'), query)) } if (path) { bindingsToApply.css = { 'active-path': ko.pureComputed(() => { const [router, route] = getRoute(ctx, path) return !router.isNavigating() && router.route() !== '' && route ? router.route().matches(route) : false }) } } // allow adjacent routers to initialize ko.tasks.schedule(() => ko.applyBindingsToNode(el, bindingsToApply)) }
var ViewModel = function(selector, settings) { var self = this; self.url = settings.url; self.selector = selector; self.settings = $.extend({}, defaultSettings, settings); self.nodeHasAuth = ko.observable(false); self.userHasAuth = ko.observable(false); self.userIsOwner = ko.observable(false); self.ownerName = ko.observable(''); self.validCredentials = ko.observable(true); self.urls = ko.observable({}); self.loadedSettings = ko.observable(false); self.bucketList = ko.observableArray([]); self.loadedBucketList = ko.observable(false); self.currentBucket = ko.observable(''); self.selectedBucket = ko.observable(''); self.encryptUploads = ko.observable(self.settings.encryptUploads); self.accessKey = ko.observable(''); self.secretKey = ko.observable(''); self.loading = ko.observable(false); self.creating = ko.observable(false); self.creatingCredentials = ko.observable(false); self.message = ko.observable(''); self.messageClass = ko.observable('text-info'); self.showSelect = ko.observable(false); self.showSettings = ko.pureComputed(function() { return self.nodeHasAuth() && self.validCredentials(); }); self.disableSettings = ko.pureComputed(function() { return !(self.userHasAuth() && self.userIsOwner()); }); self.showNewBucket = ko.pureComputed(function() { return self.userHasAuth() && self.userIsOwner(); }); self.showImport = ko.pureComputed(function() { return self.userHasAuth() && !self.nodeHasAuth(); }); self.showCreateCredentials = ko.pureComputed(function() { return self.loadedSettings() && (!self.nodeHasAuth() && !self.userHasAuth()); }); self.canChange = ko.pureComputed(function() { return self.userIsOwner() && self.nodeHasAuth(); }); self.allowSelectBucket = ko.pureComputed(function() { return (self.bucketList().length > 0 || self.loadedBucketList()) && (!self.loading()); }); self.saveButtonText = ko.pureComputed (function(){ return self.loading()? 'Saving': 'Save'; }); };
constructor ({eventEmitterOptions = {}, project}) { super({eventEmitterOptions}); this.costs = project.costs; this.labels = project.labels; this.users = project.users; this.title = ko.observable(); this.body = ko.observable(); this.cost = ko.observable(); this.works = ko.observableArray(); this.selectedLabels = ko.observableArray(); this.bodyMode = ko.observable('preview'); this.task = ko.observable(); this.task.subscribe(task => { this.title(task.title()); this.body(task.body()); this.cost(task.cost()); this.works(task.works().map(x => x.clone())); this.selectedLabels.removeAll(); task.labels().map(x => { this.selectedLabels.push(x); }); this.editWorkHistoryMode('view'); this.bodyMode('preview'); }); this.overWipLimit = ko.pureComputed(() => { const task = this.task(); const user = task && task.user(); const cost = this.cost(); return task && user && cost && user.willBeOverWipLimit(cost.value - task.cost().value); }); this.canSaveWorkHistory = ko.pureComputed(() => { return this.works().every(work => work.isValidStartTime() && work.isValidEndTime()); }); this.canUpdate = ko.pureComputed(() => { return this.canSaveWorkHistory() && !this.overWipLimit(); }); this.editWorkHistoryMode = ko.observable('view'); }
.forEach(obj => { if ('get' in obj.descriptor) { let computed = ko.pureComputed({ read: obj.descriptor.get.bind(this), write: obj.descriptor.set ? obj.descriptor.set.bind(this) : null }); Object.defineProperty(this, obj.name, { enumerable: true, configurable: false, get: computed, set: obj.descriptor.set ? computed : undefined }); // attach raw computed Object.defineProperty(this, '$' + obj.name, { enumerable: true, configurable: false, writable: obj.descriptor.set ? true : false, value: computed }); } else { let func = obj.descriptor.value; this[obj.name] = func.bind(this); } });
constructor(params) { this.gccOptsError = params.gccOptsError; this.buildCmd = params.buildCmd; this.execCmd = params.execCmd; this.compileStatus = params.compileStatus; this.compileBtnTooltip = params.compileBtnTooltip; this.compileBtnEnable = ko.pureComputed(() => { const ready = !(this.compileStatus() === 'Waiting' || this.compileStatus() === 'Compiling'); if (ready) { notify('The compiler is now online', 'green'); } else { notify('The compiler is currently busy', 'yellow'); } return ready; }); SysGlobalObservables.compileBtnEnable(this.compileBtnEnable); const $compileBtn = $('#compile-btn'); $compileBtn.click(() => { params.compileCallback(); $compileBtn.popover('hide'); }); // Initialize Bootstrap popovers $compileBtn.popover(); // We don't want the "gcc opts errors" popover to be dismissed when clicked $('#gccoptions').popover().click((e) => { e.preventDefault(); }); }
constructor: function(params) { this.super.constructor.call(this); var self = this; self.title = ko.observable(params.currentTitle).extend({ required: { params: true, message: 'Title cannot be blank.' }}); self.description = ko.observable(params.currentDescription); self.titlePlaceholder = params.currentTitle; self.descriptionPlaceholder = params.currentDescription; self.categoryOptions = params.categoryOptions; self.categoryPlaceholder = params.category; self.selectedCategory = ko.observable(params.category); self.disabled = params.disabled || false; if (!params.updateUrl) { throw new Error(language.instantiationErrorMessage); } self.updateUrl = params.updateUrl; self.node_id = params.node_id; self.originalProjectSettings = ko.observable(self.serialize()); self.dirty = ko.pureComputed(function(){ return JSON.stringify(self.originalProjectSettings()) !== JSON.stringify(self.serialize()); }); },
var BaseComment = function() { var self = this; self.abuseOptions = Object.keys(ABUSE_CATEGORIES); self._loaded = false; self.id = ko.observable(); self.page = ko.observable('node'); // Default self.errorMessage = ko.observable(); self.editErrorMessage = ko.observable(); self.replyErrorMessage = ko.observable(); self.replying = ko.observable(false); self.replyContent = ko.observable(''); self.urlForNext = ko.observable(); self.submittingReply = ko.observable(false); self.comments = ko.observableArray(); self.loadingComments = ko.observable(true); self.replyNotEmpty = ko.pureComputed(function() { return notEmpty(self.replyContent()); }); self.commentButtonText = ko.computed(function() { return self.submittingReply() ? 'Commenting' : 'Comment'; }); };
var RegistrationManager = function(node, draftsSelector, urls, createButton) { var self = this; self.node = node; self.draftsSelector = draftsSelector; self.urls = urls; self.schemas = ko.observableArray(); self.selectedSchema = ko.computed({ read: function() { return self.schemas().filter(function(s) { return s._selected(); })[0]; }, write: function(schema) { $.each(self.schemas(), function(_, s) { s._selected(false); }); schema._selected(true); } }); self.selectedSchemaId = ko.computed({ read: function() { return (self.selectedSchema() || {}).id; }, write: function(id) { var schemas = self.schemas(); var schema = schemas.filter(function(s) { return s.id === id; })[0]; self.selectedSchema(schema); } }); // TODO: convert existing registration UI to frontend impl. // self.registrations = ko.observable([]); self.drafts = ko.observableArray(); self.hasDrafts = ko.pureComputed(function() { return self.drafts().length > 0; }); self.loading = ko.observable(true); self.loading.subscribe(function(loading) { if (!loading) { createButton.removeClass('disabled'); } }); self.preview = ko.observable(false); // bound functions self.getDraftRegistrations = $.getJSON.bind(null, self.urls.list); self.getSchemas = $.getJSON.bind(null, self.urls.schemas); if (createButton) { createButton.addClass('disabled'); createButton.on('click', self.createDraftModal.bind(self)); } };
self.warningsForTool = function(tool) { return ko.pureComputed(function() { return ko.utils.arrayFilter(self.warnings(), function(warning) { return warning.tool == tool && self.href(warning.path, warning.line, warning.commit) != null; }); }); };
ko.extenders.numeric = function(target, precision) { //create a writable computed observable to intercept writes to our observable var result = ko.pureComputed({ read: target, //always return the original observables value write: function(newValue) { var current = target(), roundingMultiplier = Math.pow(10, precision), newValueAsNum = isNaN(newValue) ? 0 : parseFloat(+newValue), valueToWrite = Math.round(newValueAsNum * roundingMultiplier) / roundingMultiplier; //only write if it changed if (valueToWrite !== current) { target(valueToWrite); } else { //if the rounded value is the same, but a different value was written, force a notification for the current field if (newValue !== current) { target.notifySubscribers(valueToWrite); } } } }).extend({ notify: 'always' }); //initialize with current value to make sure it is rounded appropriately result(target()); //return the new computed observable return result; };
constructor: function(addonName, url, selector, folderPicker) { this.super.constructor.call(this, addonName, url, selector, folderPicker); this.customField = ko.observable(''); this.messages.submitSettingsSuccess = ko.pureComputed(function(){ return 'SUCCESS'; }); },
constructor: function(addonName, url, selector, folderPicker, opts) { var self = this; self.super.constructor.call(self, addonName, url, selector, folderPicker); // externalAccounts self.accounts = ko.observable([]); self.selectedFolderType = ko.pureComputed(function() { var userHasAuth = self.userHasAuth(); var selected = self.selected(); return (userHasAuth && selected) ? selected.type : ''; }); self.messages.submitSettingsSuccess = ko.pureComputed(function() { return 'Successfully linked "' + $osf.htmlEscape(self.folder().name) + '". Go to the <a href="' + self.urls().files + '">Files page</a> to view your content.'; }); // Overrides var defaults = { onPickFolder: function(evt, item) { evt.preventDefault(); var name = item.data.path !== '/' ? item.data.path : '/ (Full ' + self.addonName + ')'; self.selected({ name: name, path: item.data.path, id: item.data.id }); return false; // Prevent event propagation }, connectAccount: function() { window.location.href = this.urls().auth; } }; // Overrides self.options = $.extend({}, defaults, opts); // Treebeard config self.treebeardOptions = $.extend( {}, FolderPickerViewModel.prototype.treebeardOptions, { onPickFolder: function(evt, item) { return this.options.onPickFolder.call(this, evt, item); }.bind(this), resolveLazyloadUrl: function(item) { return item.data.urls.folders; } } ); },
const compute = (p, g, s) => { this[p] = ko.pureComputed({ read: g.bind(this), write: s ? s.bind(this) : null }); return this[p]; };
constructor (data) { this.name = ko.observable(); this.title = ko.observable(); this.type = ko.observable(); this.hasChoices = ko.pureComputed(() => this.type() == 'choice') this.update(data) }
constructor ({project}) { this.project = project; this.stages = project.stages; // 全作業時間の合計 this.totalTime = ko.pureComputed(() => { const times = this.project.tasks().map(x => x.allWorkTime()); return _.sum(times); }); this.totalTimeFormat = ko.pureComputed(() => util.dateFormatHM(this.totalTime())); // ラベルごとの全作業時間の合計 this.totalTimeLabels = ko.pureComputed(() => { const noneKey = '(none)'; const res = {}; res[noneKey] = 0; this.project.labels().forEach(label => { res[label.name()] = 0; }); this.project.tasks().forEach(task => { const labels = task.labels(); const time = task.allWorkTime(); if (labels.length) { labels.forEach(label => { res[label.name()] += time; }); } else { res[noneKey] += time; } }); return _.map(res, (time, name) => { return {name, time, format: util.dateFormatHM(time)}; }); }, this); // 過去1週間ごと人ごとの作業時間 // lastTwoWeekWorkTime()[iteration] // iteration = {day, dayFormat, users} // users[username] = {minutes, format} this.lastTwoWeekWorkTime = ko.observableArray([]); }
constructor(options) { const self = this; self.popover = options.popover; self.storageEntry = ko.observable(); self.editorLocation = options.editorLocation; self.loading = ko.pureComputed(() => { return self.storageEntry() && self.storageEntry().loading(); }); self.storageEntry.subscribe(newVal => { if (!newVal.loaded && !newVal.loading()) { if (newVal.definition.type === 'dir') { newVal.open(true); } else { newVal.loadPreview(); } } }); self.storageEntry(options.storageEntry); self.breadCrumbs = ko.pureComputed(() => { const result = []; let currentEntry = self.storageEntry(); do { result.unshift({ name: currentEntry.definition.name, isActive: currentEntry === self.storageEntry(), storageEntry: currentEntry, makeActive: function() { self.storageEntry(this.storageEntry); } }); currentEntry = currentEntry.parent; } while (currentEntry); return result; }); }
constructor: function(nodeTitle) { this.super.constructor.call(this); var self = this; this.nodeTitle = nodeTitle; this.submitEnabled = ko.observable(true); this.query = ko.observable(); this.results = ko.observableArray(); this.selection = ko.observableArray(); this.errorMsg = ko.observable(''); this.totalPages = ko.observable(0); this.includePublic = ko.observable(true); this.foundResults = ko.pureComputed(function() { return self.query() && self.results().length; }); this.noResults = ko.pureComputed(function() { return self.query() && !self.results().length; }); },
constructor(data) { this.id = null this.description = ko.observable() this.status = ko.observable() this.target = ko.observable() this.targetChoice = ko.observable() this.condition = ko.observable('ALL') this.groups = ko.observableArray([]) this.condition.subscribe((newValue) => { if (newValue != 'ALL' && newValue != 'ANY'){ this.condition('ALL') } }) this.groupsLength = ko.pureComputed(() => this.groups().length) this.hasMultipleGroups = ko.pureComputed(() => this.groupsLength() > 1) this.update(data) }
var SchoolViewModel = function() { var self = this; DateMixin.call(self); TrackedMixin.call(self); self.department = ko.observable('').extend({trimmed: true}); self.degree = ko.observable('').extend({trimmed: true}); self.institution = ko.observable('').extend({ trimmed: true, required: { onlyIf: function() { return !!self.department() || !!self.degree(); }, message: 'Institution required' } }); self.expandable = ko.computed(function() { return self.department().length > 1 || self.degree().length > 1 || self.startYear() !== null; }); self.expanded = ko.observable(false); self.toggle = function() { self.expanded(!self.expanded()); }; self.trackedProperties = [ self.institution, self.department, self.degree, self.startMonth, self.startYear, self.endMonth, self.endYear ]; var validated = ko.validatedObservable(self); //In addition to normal knockout field checks, check to see if institution is not filled out when other fields are self.institutionObjectEmpty = ko.pureComputed(function() { return !self.institution() && !self.department() && !self.degree(); }); self.isValid = ko.computed(function() { return validated.isValid(); }); };
constructor: function () { this.id = ko.observable(); this.emails = ko.observableArray(); this.primaryEmail = ko.pureComputed(function () { var emails = this.emails(); for (var i = 0; i < this.emails().length; i++) { if(emails[i].isPrimary()) { return emails[i]; } } return new UserEmail(); }.bind(this)); this.alternateEmails = ko.pureComputed(function () { var emails = this.emails(); var retval = []; for (var i = 0; i < this.emails().length; i++) { if (emails[i].isConfirmed() && !emails[i].isPrimary()) { retval.push(emails[i]); } } return retval; }.bind(this)); this.unconfirmedEmails = ko.pureComputed(function () { var emails = this.emails(); var retval = []; for (var i = 0; i < this.emails().length; i++) { if(!emails[i].isConfirmed()) { retval.push(emails[i]); } } return retval; }.bind(this)); }