Set value in Backbone.Form after fetch from the server - javascript

Hi I am newbie in Backbone and JS.
I need to fetch data from the server and put this value as the default to planProviderMode choice radio button. So i fetch the data in defaultMode variable. But the call is a asynchronous and I receive a value after the planProviderMode: defaultMode.value code has been executed.
var PlanProviderMode = Backbone.Model.extend({
url: '/rest/enrollment/step/plan-provider-mode'
});
var defaultMode = new PlanProviderMode;
defaultMode.fetch({
success: function() {
// recieve correct data
}
});
var formItems = new Backbone.Form({
template: tpl,
className: 'wizard-content',
schema: {
planProviderMode: {
template: formTpl,
type: 'Radio',
options: [
{
label: 'By Plan',
val: 'BY_PLAN',
custom: {
img: '../resources/img/by-plan.jpg'
}
},
{
label: 'By Provider',
val: 'BY_PROVIDER',
custom: {
img: '../resources/img/by-provider.jpg'
}
}
]
}
},
//here i put the default value
data: {
planProviderMode: defaultMode.value
}
});
How could I set the fetched value to the form.
Please let me know if the question is not described well. Thanks.

you should write such code in success callback function which is executed only after the fetch request is completed succesfully.
var PlanProviderMode = Backbone.Model.extend({
url: '/rest/enrollment/step/plan-provider-mode'
});
var defaultMode = new PlanProviderMode;
defaultMode.fetch({
success: function() {
// recieve correct data
//here you put the default value
data: {
planProviderMode: defaultMode.value
}
}
});
var formItems = new Backbone.Form({
template: tpl,
className: 'wizard-content',
schema: {
planProviderMode: {
template: formTpl,
type: 'Radio',
options: [
{
label: 'By Plan',
val: 'BY_PLAN',
custom: {
img: '../resources/img/by-plan.jpg'
}
},
{
label: 'By Provider',
val: 'BY_PROVIDER',
custom: {
img: '../resources/img/by-provider.jpg'
}
}
]
}
}
});

Backnone has a function called "parse" that helps you in this cases.
This function will always be called from backbone before the data from server populate the model.
Take a read in parse method.
There's a answer here.
how to override Backbone's parse function?
Hope it helps

Related

Unable to submit custom field, which extends dataview

I have a fiddle which demonstrates this strange behaviour. In a nutshell, I have a custom field which extends Ext.DataView. I need to extend dataview, because this field is supposed to have dynamic contents. This is how my field is defined:
Ext.define('Ext.ux.SimpleList', {
extend: 'Ext.DataView',
alias: 'widget.simplelist',
requires: [
'Ext.XTemplate'
],
itemSelector: 'div.record',
isFormField: true,
getFieldIdentifier: function () {
return this.name;
},
getModelData: function() {
var me = this;
var data = {};
data[me.getFieldIdentifier()] = me.getValue();
return data;
},
getSubmitData: function() { return {}; },
submitValue: true,
isValid: function () { return true; },
isDirty: function () { return true; },
validate: function () { return true; },
isFileUpload: function() { return false; },
constructor: function(config) {
Ext.applyIf(config, {
tpl: [
'{% var name = this.owner.name; %}',
'<tpl for=".">',
'<div class="record"><input record-id="{id}" type="checkbox" name="{[name]}" /> {label}</div>',
'</tpl>',
{compiled: true}
]
});
this.callParent([config]);
},
getValue: function () {
var cb = this.el.select("input").elements, i, res = [];
for (i in cb) {
if (cb.hasOwnProperty(i) && cb[i].checked) {
res.push(cb[i].getAttribute("record-id"));
}
}
return res;
},
setValue: function (values) {
//not yet implemented
}
});
And this is how I add this field to a form:
Ext.create("Ext.form.Panel",{
renderTo: Ext.getBody(),
items:[{
xtype: "textfield",
name: "text"
},{
xtype: "simplelist",
name: "list",
store: {
fields: ["id", "label", "checked"],
data: [{"id": "1", "label": "One"},{"id": "2", "label": "Two"}]
}
},{
xtype: "button",
text: "Submit",
handler: function () {
var frm = this.up("form").getForm();
console.log(frm.getFieldValues()); // it' ok
//simplelist field is not submitted
this.up("form").getForm().submit({
url: "/"
});
}
}]
});
As you can see, when I submit the form I log to the console form field values. And what is interesting about that, is that I see my custom field among those field values. So, I have a field with isFormField set to true, this field is in the list returned by form getFields() method and this field is also among those values returned by form getFieldValues() method, but still this field is not submitted. What is wrong with that and how can I fix it?
Your code uses basicForm.getFieldValues(), which calls basicForm.getValues() with some parameters, while the form while submitting uses the same method with different parameters. One of those parameters is useDataValues, which decides whether to use the getModelData or getSubmitData.
You are returning empty object in your getSubmitData method, which prevents it to correctly get the values.
All you need to change, for both methods to work in your current state, is this:
getSubmitData: function() {
return this.getModelData();
}

How can we pass current date-time to a angularjs function in a HTML page?

I am trying to get present date and pass it to the function - same-or-earlier-than But in the run-time, it does not pass date value to this class. Below is my html code. I am trying to get date from javascript and printing it for test.
the date is printed, but when passing it to the function, it doesnt work.
<div class="row">
<div class="hh-dock-page-view panel">
<div class="panel-body">
<div class="container">
<h2 class="hh-page-header">Issue Detail</h2>
<h3 class="hh-action-heading"><span ng-hide="ctrl.readOnly">Edit </span>Details - {{ctrl.returnCurDate()}} - {{ctrl.issue.issue_date}}"</h3>
<hh-model-form name="issueForm" model="ctrl.issue" page-controller="ctrl" submit-success="ctrl.submitSuccess" hide-actions="ctrl.readOnly">
<h2 class="hh-page-header extra-margin">{{modelFormCtrl.model.provider_name_spec_prac}} - {{ctrl.issue.issue_date}}</h2>
<div class="row">
<div class="col-sm-6">
<hh-field-messages>
<label for="issue_date">Issue Date</label>
<hh-american-date-field
id="issue_date"
name="issue_date"
ng-model="modelFormCtrl.model.issue_date"
ng-blur="modelFormCtrl.pageController.setStatus(this)"
ng-disabled="modelFormCtrl.pageController.readOnly"
same-or-earlier-than="{{ctrl.issue.issue_date}}"
same-or-earlier-than-msg="Enter a date that is on or before Resolution Date."
>
</hh-american-date-field>
</hh-field-messages>
<div class="hh-breath"></div>
</div>
</div>
</hh-model-form>
</div>
</div>
and here below is my angularjs file:
angular.module('Prm')
.controller('IssueDetailController',
['$scope', '$q', '$route', '$location', '$routeParams', 'moment', 'IssueService', 'IssuePriorityService', 'ActivityService',
'ProviderService', 'DirtyFormCheckingService', 'ConfirmBox', 'ErrorAlertService', 'AlertBoxService', 'DateService',
'ReferenceTableDataAdapter',
function ($scope, $q, $route, $location, $routeParams, moment, IssueService, IssuePriorityService, ActivityService, ProviderService,
DirtyFormCheckingService, ConfirmBox, ErrorAlertService, AlertBoxService, DateService,
ReferenceTableDataAdapter){
'use strict';
var ctrl = this,
isExisting = false,
issuePriority = null,
initPromises = [];
var currentUser = cpm.authentication.user.report_ownership_role_code;
ctrl.isAdmin = cpm.authentication.user.dss_role_list.split(",").includes('USERADMIN');
ctrl.readOnly = true;
var getNameForEdit = function(row) {
if (ctrl.readOnly) return 'View';
return 'Edit';
};
ctrl.providerAdapter = ReferenceTableDataAdapter('provider');
ctrl.ownerRoleAdapter = ReferenceTableDataAdapter('dss_report_owner_contact');
ctrl.providerIssueStatusAdapter = ReferenceTableDataAdapter('provider_issue_status');
ctrl.providerIssueSiteAdapter = ReferenceTableDataAdapter('provider_issue_site');
ctrl.providerIssuePriorityAdapter = ReferenceTableDataAdapter('provider_issue_priority');
ctrl.providerIssueCategoryAdapter = ReferenceTableDataAdapter('provider_issue_category');
if($routeParams.issue_code) {
isExisting = true;
initPromises.push(IssueService.get({id: $routeParams.issue_code}).$promise.then(function (data) {
ctrl.issue = data;
// placing this on the controller for the Parent Issue grid (if exists). Grid needs list of objects...
ctrl.parentActivities = [{'parent_provider_activity':ctrl.issue.parent_provider_activity,
'parent_provider_activity_activity_date':ctrl.issue.parent_provider_activity_activity_date,
'parent_provider_activity_description': ctrl.issue.parent_provider_activity_description}];
}));
} else {
ctrl.issue = IssueService.wrapData({
description: '',
resolution: '',
status: 'N',
site: '',
priority: 'N',
category: '',
provider: $routeParams.provider_code,
issue_date: new Date(),
owner_role: currentUser
});
ctrl.hide_resolution = true;
//ctrl.issue_date = new Date();
/* An issue may be created from a provider */
if($routeParams.provider_code) {
initPromises.push(ProviderService.get({id: $routeParams.provider_code}).$promise.then(function (data) {
ctrl.issue.provider = data.provider_code;
}));
}
}
/* Issues can have their due dates set based on their priority */
initPromises.push(IssuePriorityService.getPrioritiesMap().then(function (priorities) {
issuePriority = priorities;
if(!isExisting) {
ctrl.issue.due_date = moment(DateService.todayAsUtcDate()).add(issuePriority.N, 'day').toDate();
}
}));
/* Initialization */
$q.all(initPromises).then(function () {
/* Allow editing existing record only by owner & admins */
if(!isExisting || ctrl.isAdmin || ctrl.issue.owner_role === cpm.authentication.user.report_ownership_role_code) {
ctrl.readOnly = false;
}
// TODO: when grid actions are added
// ctrl.activitiesGrid.hideAddButton = ctrl.readOnly;
DirtyFormCheckingService($scope, 'issueForm', ctrl.issue);
});
ctrl.setDueDate = function (newModel, newCode) {
ctrl.issue.due_date = moment(ctrl.issue.issue_date).add(issuePriority[newCode], 'day').toDate();
};
ctrl.setResolutionDate = function (newModel, newCode) {
// ctrl.hide_resolution = (newCode !== 'R');
if (newCode == 'R') {
ctrl.issue.resolution_date = DateService.todayAsUtcDate();
} else {
ctrl.issue.resolution_date = null;
}
};
$scope.$watch('ctrl.issue.status', function (newCode) {
if(ctrl.issue) {
ctrl.hide_resolution = (newCode !== 'R');
}
});
ctrl.setStatus = function (event){
if (ctrl.issue.resolution_date) {
ctrl.issue.status = "R";
} else {
ctrl.issue.status = "N";
}
};
ctrl.submitSuccess = function() {
$location.url('/');
};
ctrl.parentActivityConfig = {
modelSetName: 'parentIssues',
actions: {
editRow: {
label: function(row) {
return ctrl.readOnly ? 'View' : 'Edit';
},
active: true,
callback: function(row){
$location.path('/activity/'+ctrl.issue.parent_provider_activity);
}
},
deleteRow: {
active: false
}
},
rowActions: ['editRow'],
columns: [
{col_description: 'Activity Date',
datatype: 'date',
model_field: 'parent_provider_activity_activity_date',
field_type: 'american_date',
field_name: 'activityDate'
},
{col_description: 'Description',
datatype: 'text',
model_field: 'parent_provider_activity_description',
field_type: 'text',
field_name: 'description'
},
]
};
ctrl.activitiesTableConfig = {
modelSetName: "activities",
serializerChildName: 'activities',
actions: {
addRow: {
label: 'Add Activity',
callback: function(){
$location.path('/provider/'+ctrl.issue.provider+'/add_activity/'+ctrl.issue.provider_issue_code);
},
active: function(row) {return !ctrl.readOnly;}
},
editRow: {
label: function(row) {
return getNameForEdit(row.modelSet);
},
active: true,
callback: function(row){
$location.path('/activity/'+row.modelSet.provider_activity_code);
}
},
deleteRow: {
active: function(row) {return !ctrl.readOnly;},
callback: function(row){
_.pull(ctrl.issue.activities, row.modelSet);
}
}
},
rowActions: ['editRow', 'deleteRow'],
columns: [
{col_description: 'Date',
datatype: 'date',
model_field: 'activity_date',
field_type: 'american-date',
field_name: 'activity_date'
},
{col_description: 'Type',
datatype: 'text',
model_field: 'provider_activity_type_description',
field_type: 'text',
field_name: 'provider_activity_type_description'
},
{col_description: 'Notes',
datatype: 'text',
model_field: 'description',
field_type: 'text',
field_name: 'description'
},
{col_description: 'Owner',
datatype: 'text',
model_field: 'owner_comp_name',
field_type: 'text',
field_name: 'owner_comp_name'
},
]
};
}]);
I'm trying my best to understand your question, but there's a lot of code to look through here. I do understand that you're trying to pass the current date to a function named "same-or-earlier than." However I can't seem to find a function with that name in your controller file.
I'm assuming that you've got a custom directive (attribute directive) that accepts the current date.
Either way, a simple solution for your problem of passing the current date could be to write a small function that when invoked returns the date using Javascript's native "Date" object.
Perhaps like this in your controller:
ctrl.returnCurDate = function() {
return new Date();
};
That way in your markup, you can invoke the method we've defined since it's attached to the scope of your controller.
same-or-earlier-than = "ctrl.returnCurDate()"
I hope I'm answering your problem in a relevant fashion, please feel free to ask further if I've misunderstood your question.
Best of luck.
P.S. Inherently there are some pain-in-the-butt formatting issues that come with using JS's native Date constructor, I would consider using a library such as "Moment.js" to relieve you of parsing the returned value when invoking:
new Date();

Issues with dynamic routing using meteor-autoform and iron:router

What I am trying to do is create a form with meteor-autoform that will redirect the user to a newly generated route on submit. My thought process is that I can take the submissions _id and use it for an iron:router parameter. What I have so far looks as followed:
Creation of Form
Submits = new Meteor.Collection('Submits');
Submits.allow({
insert: function(username, doc){
return !!username;
}
});
SubmitSchema = new SimpleSchema({
title: {
type: String,
label: "Title"
},
subject:{
type: String,
label: "Subject"
},
summary:{
type: String,
label: "Summary"
},
author:{
type: String,
label: "Author",
autoValue: function() {
return this.userId
},
autoform: {
type: "hidden"
}
},
createdAt: {
type: Date,
label: "Created At",
autoValue: function(){
return new Date()
},
autoform: {
type: "hidden"
}
}
});
Submits.attachSchema( SubmitSchema );
Routing
Router.route('/submit', {
layoutTemplate: 'submitLayout',
waitOn: function() { return Meteor.subscribe("Submits"); },
loadingTemplate: 'loading'
});
Router.route('/submit/:_id', {
name: 'formDisplay',
data: function() {
return Submits.findOne({this.params._id});
}
});
And then I just have the average publish and find calls. My issues are I'm not sure how to perform the redirect on submit, and I am not sure how to display the form results on the newly generated route.
Any help would be appreciated.
I was able to do it by adding an autoform.hook and changing my routing a bit.
Autoform hook:
AutoForm.addHooks('insertSubmit', {
onSuccess: function(doc) {
Router.go('formDisplay',{_id: this.docId});
}
})
Routing:
Router.route('/submit/:_id', {
name: 'submitLayout',
data: function() { return Products.findOne(this.params._id);}
});
I got this information from this post:
Route to the new data submitted by Meteor autoform using iron router?

Submit url parameter with form to meteor method

I am using aldeed:autoform in order to render a form and run its result through a Meteor.method(). My form looks as follows:
SelectPlanTemplates = new SimpleSchema({
templates: {
type: [String],
autoform: {
options: function() {
return PlanTemplates.find().map(function(doc) {
return { label: doc.title, value: doc._id };
});
},
noselect: true
}
},
userId: {
type: String,
allowedValues: function() {
return Meteor.users.find().map(function(doc) {
return doc._id;
});
},
autoform: {
omit: true
}
}
});
On my template, I just do the following.
+ionContent
+quickForm(schema="SelectPlanTemplates" id="SelectPlanTemplatesForm" type="method" meteormethod="createPlanFromTemplates")
My url is constructed like /plan/from_templates/{:userId}. I tried creating a hook to add the user id before submitting it.
AutoForm.hooks({
SelectPlanTemplatesForm: {
before: {
method: function(doc) {
doc.userId = Router.current().params.userId;
return doc;
}
}
}
});
However, it never seems to get to this hook.
How would I take a route parameter and pass it with my form to a meteor method with auto form?
I think I figured out a little bit of a weird way of do it.
In the router:
this.route('selectPlans', {
waitOn: function() {
return Meteor.subscribe('plan_templates');
},
path: '/select/plan_templates/:_id',
template: 'selectTemplates',
data: function() {
return new selectPlanTemplates({ userId: this.params._id });
}
});
Then I added doc=this to my template

ExtJS controller probelem. Uncaught TypeError: Object [object Object] has no method 'setSortState'

T writing code using ExtJS4.0.1, MVC architecture. And when I develop main form I meet problem with search extension for web site.
When I was trying to create new widget in controller, I need render result in subpanel. and so when I write sample code I meet following problem:
**Uncaught TypeError: Object [object Object] has no method 'setSortState'**
I cannot understand why it gives that error message. I need some help to resolve that problem.
Below I want to show my code:
//Panel which is showing to user
Ext.define('Semantics.view.main.menuView', {
extend: 'Ext.panel.Panel',
layout: 'fit',
alias: 'widget.Menu',
title: "",
tbar: [
{
//search field
name:'mainSearchText',
id:'mainSearchText',
xtype: 'textfield',
defaultValue: 'Search',
height: 20
},
{
name:'mainSearchButton',
id:'mainSearchButton',
xtype: 'button',
text: 'Find',
height: 20
}
]
});
//controller for search request
Ext.define('Semantics.controller.main.mainController', {
extend: 'Ext.app.Controller',
views: ['main.menuView','mainSearch.MainSearchResultForm'],
refs: [
{ ref: 'menuPanel', selector: 'Menu' },
{ ref:'mainSearchText',selector:'#mainSearchText'},
{ref: 'mainSearchForm',selector:'#mainSearchForm'},
{ref:'MainSearchGrid',selector:'#MainSearchGrid'}
],
init: function () {
this.control({
'Menu': {
render: this.onPanelRendered
},
'Menu button[name="mainSearchButton"]': {
click: this.onButtonClick
}
});
},
onButtonClick: function (button) {
var me = this;
if(button.name=="mainSearchButton") {
var mtextFiled = me.getMainSearchText().getValue();
console.log(mtextFiled);
Ext.Ajax.request({
scope: this,
url: 'app/mainSearchT/findText/',
method: 'POST',
params: {
text: me.getMainSearchText().getValue()
},
success: function (result) {
mainPanel = me.getMenuPanel();
mainPanel.removeAll(true);
loadingMask = new Ext.LoadMask(mainPanel, { msg: "Loading" });
loadingMask.show();
var mname = 'MainSearchResultForm';
var start_info_panel = Ext.widget(mname);
mainPanel.items.add(start_info_panel);
loadingMask.hide();
mainPanel.doLayout(); //that line gives that error
},
failure: function (result) {
console.log(result);
}
});
}
},
onPanelRendered: function () {
}
});
I encountered the same error when I included unsupported xtype in Ext.grid.Panel columns. I had to remove the xtype, which resolved the problem.

Categories

Resources