Meteor simple schema and collection2 autoValue only firing once - javascript

I can't get autoValue to fire more than once, even though the docs suggest it always runs:
var saleItem = new SimpleSchema({
productId: {
label: 'Product Id',
type: String
},
sku: {
label: 'Item Name',
type: String
},
name: {
label: 'Item Name',
type: String
},
price: {
label: 'Item Price',
type: Number,
decimal: true,
min: 0
},
qty: {
label: 'Item Quantity',
type: Number,
min: 0
},
subtotal: {
label: 'Item Subtotal',
type: Number,
decimal: true,
autoValue: function(doc) {
console.log(doc);
return doc.$push.items.price * doc.$push.items.qty;
}
}
});
The console logs a JSON document the first time the document is inserted, but not thereafter. It's important to note that this schema is a sub-schema.

Related

What happened to this error? I changed the class name of the table, but I cannot change it and this error occurs?

Help Me please !! What happened to this error? I changed the class name of the table, but I cannot change it and this error occurs?
new gridjs.Grid({
columns: [{ name: 'ID', width: '60px' },
{ name: 'Name', width: '200px' },
{ name: 'Position', width: '300px' },
{ name: 'Email', width: '200px' },
{ name: 'Tel', width: '100px' },
{ name: '', width: '40px', sort: false }],
sort: true,
search: true,
pagination: {
limit: 5,
},
className: {
table: 'table',
thead: 'thead-dark'
},
language: {
'search': {
'placeholder': ' Search...'
},
},
server: {
url: 'http://localhost:55289/ManageUser/GetUserList',
then: data => data.map(user => [user.id,
user.first_name + '\xa0\xa0\xa0' + user.last_name,
user.position, user.email,
user.tel_mobile,
gridjs.html(`<a id="button-delete" href="/ManageUser/Delete/${user.id}"><button class="btn btn-danger"><i class="fa fa-close"></i></button></a>`)])
}
}).render(document.getElementById("user-table"));
As Tammy mentioned, you need to define a custom id for your column:
const grid = new Grid({
columns: [{
id: 'name',
name: 'Name'
}, {
id: 'email',
name: 'Email'
}, {
id: 'phoneNumber',
name: 'Phone Number'
}],
data: [
{ name: 'John', email: 'john#example.com', phoneNumber: '(353) 01 222 3333' },
{ name: 'Mark', email: 'mark#gmail.com', phoneNumber: '(01) 22 888 4444' },
]
});
Demo: https://gridjs.io/docs/examples/import-json
I had the same issue:
Could not find a valid ID for one of the columns.
Make sure a valid "id" is set for all columns
And the fix was what Tammy mentions, I had an empty named column.

How to access to nested objects keys

I am trying to get the value from a data file with nested objects.
I want to create a label for each entry that i have under the EN object. So I would like to end up having a "mail" label a "quote" label and a "phone" label.
In the label I want to put the content of tabLabel and tabIcon by accessing it.
With Object.Keys() i can see the strings but when I try to console.log them I get undefined.
I did this function but is not working:
function generateLabel() {
const keys = Object.keys(TabFormData.EN);
for (let i = 0; i < keys; i += 1) {
return `
<div class="${ID}_tab-form__headerItemWrap">
<label for="taLabel-here"><i class="tabIcon-here"></i></label>
</div>
`;
}
}
This is the data:
const TabFormData = {
EN: {
mail: [
{
tabLabel: 'Email Our Team',
tabIcon: 'fa fa-envelope',
},
{
label: 'First Name',
type: 'text',
name: 'name',
required: true,
hint: 'Please, provide your Name.',
},
{
label: 'Last Name',
type: 'text',
name: 'surname',
required: true,
hint: 'Please, provide your Last Name.',
},
{
label: 'Email Address',
type: 'email',
name: 'email',
required: true,
hint: 'Please, provide a valid email.',
},
{
label: 'Your Message',
type: 'textarea',
required: true,
name: 'message',
hint: 'Write us a message.',
rows: 20,
cols: 50,
},
{
label: 'About You',
required: true,
select: [
'Home use',
'Business use',
'Freelance, professional',
],
},
],
quote: [
{
tabLabel: 'Request a Quote',
tabIcon: 'fa fa-file-invoice-dollar',
},
{
label: 'First Name',
type: 'text',
name: 'name',
required: true,
hint: 'Please, provide your Name.',
},
{
label: 'Last Name',
type: 'text',
name: 'surname',
required: true,
hint: 'Please, provide your Last Name.',
},
{
label: 'Phone Number',
type: 'number',
name: 'telephone',
required: true,
hint: 'Please, provide a valid number',
},
{
label: 'Email Address',
type: 'email',
name: 'email',
required: false,
hint: 'Please, provide a valid email.',
},
{
label: 'Your Message',
type: 'textarea',
required: false,
name: 'message',
hint: 'Write us a message.',
rows: 20,
cols: 50,
},
{
label: 'About You',
required: true,
select: [
'Home use',
'Business use',
'Freelance, professional',
],
},
],
call: [
{
tabLabel: 'Call Me Back',
tabIcon: 'fa fa-phone',
},
{
label: 'First Name',
type: 'text',
name: 'name',
required: true,
hint: 'Please, provide your Name.',
},
{
label: 'Last Name',
type: 'text',
name: 'surname',
required: true,
hint: 'Please, provide your Last Name.',
},
{
label: 'Phone Number',
type: 'number',
name: 'telephone',
required: true,
hint: 'Please, provide a valid number',
},
{
label: 'About You',
required: true,
select: [
'Home use',
'Business use',
'Freelance, professional',
],
},
],
},
IT: {
},
};
Your problem is in the loop.
for (let i = 0; i < keys; i += 1)
In here you're checking if i is less than an array object, which is not what you want.
You want to compare i against the number of items in the array.
So that would become this:
for (let i = 0; i < keys.length; i += 1)
Your string literal is also wrong, ID in this case is an undefined variable. I assume you want the name of the key. For this issue it should become:
<div class="${keys[i]}_tab-form__headerItemWrap">
Also, once you return from the for loop, it'll automatically break on the first iteration (meaning you'll always get only one item). What you could do is build your whole string first then return it.
That would make your function become:
function generateLabel() {
const keys = Object.keys(TabFormData.EN);
var str = "";
for (let i = 0; i < keys.length; i += 1) {
str +=
`<div class="${keys[i]}_tab-form__headerItemWrap">
<label for="taLabel-here"><i class="tabIcon-here"></i></label>
</div>
`;
}
return str;
}
Here's a Fiddle.
If I understand correctly, you are looking something like this:
let cb = (v) => `<div class="${v[0]}"><label for="${v[1][0]['tabLabel']}"><i class="${v[1][0]['tabIcon']}"></i></label></div>`
Object.entries(TabFormData['EN']).map(cb);
Object.keys() returns the only the keys of the object, however it seems that you want to access the values as well. So, in your case Object.entries() is preferred.
I recommend to read the link below:
https://javascript.info/keys-values-entries
As reported by #Adriani6, you have issues in the loop, but to actually answer your question, here's how to access the nested objects:
function generateLabel() {
const keys = Object.keys(TabFormData.EN);
for (let i = 0; i < keys.length; i += 1) {
let currentTabObject = TabFormData.EN[keys[i]];
console.log(currentTabObject[0].tabLabel);
console.log(currentTabObject[0].tabIcon);
}
}
Assuming you assign TabFormData.EN to a variable called data and the Object.keys result of TabFormData.EN to a variable called keys, you can use:
${keys[i]} to retrieve the name and append it to your div classname,
${data[keys[i]][0].tabLabel} to retrieve the tabLabel property value and append it to your <label> tag, and
${data[keys[i]][0].tabIcon} to retrieve the tabIcon property value and append it to your <i> tag.
You can ignore the <hr> tags, the <button> tag and the rendered <div> tags and just check the object property references in the code snippet below if you want. They are just there for illustrating the code results in the jsFiddle and the code snippet below:
/* JavaScript */
var x = document.getElementById('abc');
var btn = document.getElementById('btn');
function generateLabel() {
const data = TabFormData.EN;
const keys = Object.keys(data);
for (let i = 0; i < keys.length; i += 1) {
x.innerHTML += `
<hr>
<div class="${keys[i]}_tab-form__headerItemWrap">
<label for="${data[keys[i]][0].tabLabel}">
<i class="${data[keys[i]][0].tabIcon}-here">
class of this div is ${keys[i]}_tab-form__headerItemWrap, label for this is ${data[keys[i]][0].tabLabel} and icon is ${data[keys[i]][0].tabIcon}
</i>
</label>
</div>
<hr>`
}
}
btn.addEventListener('click', generateLabel);
const TabFormData = {
EN: {
mail: [
{
tabLabel: 'Email Our Team',
tabIcon: 'fa fa-envelope',
},
{
label: 'First Name',
type: 'text',
name: 'name',
required: true,
hint: 'Please, provide your Name.',
},
{
label: 'Last Name',
type: 'text',
name: 'surname',
required: true,
hint: 'Please, provide your Last Name.',
},
{
label: 'Email Address',
type: 'email',
name: 'email',
required: true,
hint: 'Please, provide a valid email.',
},
{
label: 'Your Message',
type: 'textarea',
required: true,
name: 'message',
hint: 'Write us a message.',
rows: 20,
cols: 50,
},
{
label: 'About You',
required: true,
select: [
'Home use',
'Business use',
'Freelance, professional',
],
},
],
quote: [
{
tabLabel: 'Request a Quote',
tabIcon: 'fa fa-file-invoice-dollar',
},
{
label: 'First Name',
type: 'text',
name: 'name',
required: true,
hint: 'Please, provide your Name.',
},
{
label: 'Last Name',
type: 'text',
name: 'surname',
required: true,
hint: 'Please, provide your Last Name.',
},
{
label: 'Phone Number',
type: 'number',
name: 'telephone',
required: true,
hint: 'Please, provide a valid number',
},
{
label: 'Email Address',
type: 'email',
name: 'email',
required: false,
hint: 'Please, provide a valid email.',
},
{
label: 'Your Message',
type: 'textarea',
required: false,
name: 'message',
hint: 'Write us a message.',
rows: 20,
cols: 50,
},
{
label: 'About You',
required: true,
select: [
'Home use',
'Business use',
'Freelance, professional',
],
},
],
call: [
{
tabLabel: 'Call Me Back',
tabIcon: 'fa fa-phone',
},
{
label: 'First Name',
type: 'text',
name: 'name',
required: true,
hint: 'Please, provide your Name.',
},
{
label: 'Last Name',
type: 'text',
name: 'surname',
required: true,
hint: 'Please, provide your Last Name.',
},
{
label: 'Phone Number',
type: 'number',
name: 'telephone',
required: true,
hint: 'Please, provide a valid number',
},
{
label: 'About You',
required: true,
select: [
'Home use',
'Business use',
'Freelance, professional',
],
},
],
},
IT: {
},
};
/* CSS */
<!-- HTML -->
<button id="btn">
Click Me
</button>
<div id="abc"></div>

JSGrid add icon instead of text based on true or false value

I am trying to add an icon(a lock) based on whether a value is true or false in a JSGrid.
I have a variable called SoftLock, and if this is true I want to insert a lock icon on the grid.
I have the following fields but am unsure about how to continue:
var fields = [
{ name: 'ID', type: 'text', visible: false },
//THIS FIELD BELOW
{ name: 'SoftLock', type: 'text', title: 'Locked', formatter : function () {return "<span class='fa fa-lock'><i class='fa fa-lock' aria-hidden='true'></i></span>"} },
//THIS FIELD ABOVE
{ name: 'Status', type: 'select', items: MatterStatusEnum.List, valueField: 'Id', textField: 'Name', width: 70, title: 'Account Status' },
{ name: 'AttorneyRef', type: 'text', title: 'Reference' },
{ name: 'Investors', type: 'text', title: 'Investor/s' },
{ name: 'AccountNumber', type: 'text', width: 70, title: 'Account Number' },
{ name: 'IntermediaryName', type: 'text', title: 'Intermediary Name' },
{ name: 'CreatedBy', type: 'text', title: 'Captured By' },
{ name: 'RequestedDate', type: 'date', title: 'Requested Date'}
];
I have used the formatter with no luck. Also, how can I show an icon if true, and nothing if false.
Any help would be appreciated.
I solved this by using the itemTemplate as follows:
{
name: 'SoftLock', type: 'text', title: 'Locked', width: 30,
itemTemplate : function (value, item) {
var iconClass = "";
if (value == true) {
iconClass = "fa fa-lock"; //this is my class with an icon
}
return $("<span>").attr("class", iconClass);
}
Simple as that :)
Much later but try the following
{
type: "control",
editButton: true
}
Also the answer is better described in the formal documentation.
http://js-grid.com/docs/#control

How to remove treeview child node using jquery

I have a treeview like below, i need to remove one child from the list based on the user. Can any one tell me how to remove the child from the treeview.
var treedata = [
{
label: 'Floor', type: 'Country',
children: [
{
label: 'Bangalore', type: 'Location',
children: [{ label: 'Technopolis', type: 'facility', id: 1 }, { label: 'Ecity Tower-2', type: 'facility', id: 2 }, { label: 'Bagmane', type: 'facility', id: 3 }, { label: 'Cyber Park', type: 'facility', id: 4 }]
},
{
label: 'Hyderabad', type: 'Location',
children: [{ label: 'Hitech City ', type: 'facility', id: 5 }, { label: 'Cyber City', type: 'facility', id: 6 }]
},
{
label: 'Chennai', type: 'Location',
children: [{ label: 'XXX', type: 'facility', id: 7 }]
},
{
label: 'Mumbai', type: 'facility', id: 8
}
]
},
{
label: 'Role Administration', type: 'Role',
children: [{ label: 'Assign Role', type: 'Role', id: 1 }]
},
{
label: 'Hoteling Admin', type: 'Hoteling',
children: [{ label: 'Hoteling', type: 'Hoteling', id: 1 }]
}
];
The above is my jquery tree data. I want to remove the role administration if the user is a normal user by checking the user role.
Anyone help me how to do using jquery.
Thanks
You can use $.grep() to filter the array to a new array based on whatever conditions you want.
var userRole='normal';
if( userRole === 'normal'){
treeview = $.grep(treeview, function(item){
return item.label != 'Role Administration';
});
}
grep() API docs

ExtJS 3.3 Format.Util.Ext.util.Format.dateRenderer returning NaN

The Store
var timesheet = new Ext.data.JsonStore(
{
root: 'timesheetEntries',
url: 'php/scripts/timecardEntry.script.php',
storeId: 'timesheet',
autoLoad: true,
fields: [
{ name: 'id', type: 'integer' },
{ name: 'user_id', type: 'integer' },
{ name: 'ticket_number', type: 'integer' },
{ name: 'description', type: 'string' },
{ name: 'start_time', type: 'string' },
{ name: 'stop_time', type: 'string' },
{ name: 'client_id', type: 'integer' },
{ name: 'is_billable', type: 'integer' }
]
}
);
A section of my GridPanel code:
columns: [
{
id: 'ticket_number',
header: 'Ticket #',
dataIndex: 'ticket_number'
},
{
id: 'description',
header: 'Description',
dataIndex: 'description'
},
{
id: 'start_time',
header: 'Start',
dataIndex: 'start_time',
renderer: Ext.util.Format.dateRenderer('m/d/Y H:i:s')
}
...
From the server, I receive this JSON string:
{
timesheetEntries:[
{
"id":"1",
"user_id":"1",
"description":null,
"start_time":"2010-11-13 11:30:00",
"stop_time":"2010-11-13 15:50:10",
"client_id":null,
"is_billable":"0"
}
My grid panel renders fine. However, my start and stop time columns read 'NaN/NaN/NaN NaN:NaN:NaN' and I don't know why.
If your data has "2010-11-13 11:30:00" shouldn't your format be 'Y-m-d H:i:s'?
EDIT: Sorry, the grid config should be OK -- I was referring to the dateFormat value in your store's field definition, which should be 'Y-m-d H:i:s' so that your incoming data can be properly mapped to your column model. You should also include type: 'date'. You're not showing your store config, but the problem is likely one of those things being wrong.
Try this
function renderDate(v,params,record)
{
var dt = new Date(v);
if (!isNaN(dt.getDay())) {
return dt.format('d/m/Y');
}
return '-';
}
A very simple way to do it:
return Ext.util.Format.date(val,'m/d/Y');

Categories

Resources