So I have a poll template that can have as many questions as the user wants. How do I insert all the questions into an element of a collection? Since I only had three before, I inserted them manually like this:
var newPoll = {
question: event.target.question.value,
choices: [
{ text: event.target.choice1.value, votes: 0 },
{ text: event.target.choice2.value, votes: 0 },
{ text: event.target.choice3.value, votes: 0 }
],
usersWhoVoted: [],
poll_is_open: true,
time_poll_closed: null,
};
If I can have now as many choices as I want, how do I insert all of them?
If you have implemented a local collection to store Choices related data, you could use the cursor.map() function to loop over your collection, return proper objects into an array and finally set the corresponding data:
if (Meteor.isClient) {
Template.pollForm.events({
'click #save-form': function(event, template) {
var choices = Choices.find().map((choice) => ({
text: template.find("input[name=" + choice.name + "]").value,
votes: 0
}));
var newPoll = {
question: event.target.question.value,
choices: choices,
usersWhoVoted: [],
poll_is_open: true,
time_poll_closed: null
};
Polls.insert(newPoll);
}
});
}
Related
Hi to every one reading this. I am struggling with a PDF.js problem. I am using this library: https://github.com/edisonneza/jspdf-invoice-template to render a PDF with data that I am getting from an internal axios route that returns orders. This orders are listed with a checkbox, for the orders checked I generate a new array with the objects of the different orders checked.
Up to this I was doing fine, but the next thing I need is to generate this PDFs. I got it to work rendering one single pdf with the data order, but i would like to generete a PDF with (N) numbers of pages, using the checked orders to print with a button.
Below are the blocks of the code that i wrote.
printAllbtn.addEventListener('click',function(){
try {
if(ordersSelectedToPrint.length \> 1){
console.log(ordersSelectedToPrint);
for (let orderPrint of ordersSelectedToPrint) {
let pdfObject = jsPDFInvoiceTemplate.default(props);
console.log( 'object created' + pdfObject + orderPrint)
var props = {
outputType: jsPDFInvoiceTemplate.OutputType.Save,
returnJsPDFDocObject: true,
fileName: "remito",
orientationLandscape: false,
compress: true,
business: {
name: "Isidorito",
address: "San Pedro, Buenos",
phone: "(3329) 069 11 11 111",
email: "contacto#isidorito.com",
website: "www.isidorito.com.ar/nosotros",
},
contact: {
label: "Remito dirigito a:",
name: `${orderPrint.cliente.dueño}`,
address:`${orderPrint.cliente.direccion}`,
phone: `${orderPrint.cliente.telefono1}`,
email: `${orderPrint.cliente.correo}`,
},
invoice: {
label: "Pedido #",
num: 19,
invDate: `${orderPrint.createdAt}`,
invGenDate: `28/10/2022`,
headerBorder: false,
tableBodyBorder: false,
header: [
{
title: "#",
style: {
width: 10
}
},
{
title: "Productos descripción",
style: {
width: 70
}
},
{
title: "Cantidad ",
style: {
width:20
}
},
{ title: "Por Unidad",
style:{width:30}},
// { title: "Cantidad"},
{ title: "Por tot",
style:{
width:30
}},
{ title: "Total",
style:{
width:30
}}
],
table: Array.from(orderPrint.productosPedidosNombre).forEach(function(productoIm, index){[
index + 1,
`${productoIm.nombre} - ${productoIm.marca} - ${productoIm.presentacion}`,
`${productoIm.cantidad}`,
`${productoIm.cantidad}`,
`${productoIm.cantidad}`,
`${productoIm.cantidad}`,
]}),
invDescLabel: "Cliente:",
invDesc: `${orderPrint.cliente.nombreLocal}`,
},
footer: {
text: "Este remito generado digitalmente es valido para el pedido realizado",
},
pageEnable: true,
pageLabel: "Page ",
};
} } } catch (error) { console.log(error); }
});
The first note is that "orderPrint.productosPedidosNombre" is an array of products of the order. In the example from the documentation its represented in this way.
table: Array.from(Array(10), (item, index)=>([
index + 1,
"There are many variations ",
"Lorem Ipsum is simply dummy text dummy text ",
200.5,
4.5,
"m2",
400.5
])),
And the way I generate the PDF is:
let pdfObject = jsPDFInvoiceTemplate.default(props);
First I would like to know if it is possible the loops and iteration to generate this type of single file with N number of order pages, and each page with different data. It's possible with this library.
Thanks you. It's my second question I've asked in StackOverflow, so I welcome the feedback on the how to ask in stack overflow.
In future I have many if condition, any idea to shorten the if condition for (Render Badge items)?
Today I just only have 4 item if in the future I have 20 or maybe 100 item, is it i need to code the if for 20 or 100 times?
I have tried many method, but I don't know how to make it.
Render Dynamic List
const medals = productItem.goldmedal || productItem.newitem || productItem.freedelivery;
if (medals) {
const iconBadge = $("<ul>", { class: 'icons' });
function createMedal(src, text) {
const badge =
$("<li>", { class: 'icon' })
.append($('<a>', { class: 'tpsTooltip skeleton_hide', href: '###', 'data-tippy-content': text })
.append($('<img>', { src: src, alt: text })))
.append($('<div>', { class: 'pl-placeholder_skeleton pl-placeholder_liIcon' }));
iconBadge.append(badge);
}
createFeatureIcon.append(iconBadge);
//Render Badge items (Below is the if condition code)
if (productItem.goldmedal) {
createMedal(plSettings.goldMetalSrc, plSettings.goldMetalText)
}
if (productItem.newitem) {
createMedal(plSettings.newItemSrc, plSettings.newItemText)
}
if (productItem.newshop) {
createMedal(plSettings.newShopSrc, plSettings.newShopText)
}
if (productItem.freedelivery) {
createMedal(plSettings.freeDeliverySrc, plSettings.freeDeliveryText)
}
}
Settings
//Settings
var plSettings = $.extend({
mainClass: 'item-wrapper',
itemWrapperClass: 'item ripple-effect ripple-joya itemShadowLight',
goldMetalSrc: '/img/tps/gold.png',
goldMetalText: 'Gold Medal sellers stand out from millions of sellers, bringing more trust and peace of mind to your shopping experience',
newItemSrc: '/img/tps/new.png',
newItemText: 'New item',
sellermedalSrc: '/img/tps/seller.png',
sellermedalText: 'Top Seller',
newShopSrc: '/img/tps/newshop.png',
newShopText: 'New Shop In Joyacart',
freeDeliverySrc: '/img/tps/freedelivery.png',
freeDeliveryText: 'Free Delivery'
});
example data is below:
var data = {
productList: [
{
id: "62276197-6059-4c21-9b40-c5b1d277e85d",
link: "javascript:void(0)",
imgurl: "/img/upload/png/joyacart_000001_12032019.png",
text: 'Product 001',
goldmedal: false,
newitem: true,
newshop: true,
freedelivery: true
},
{
id: "59de8216-052d-4e51-9f7d-7e96642ded62",
link: "javascript:void(0)",
imgurl: "/img/upload/png/joyacart_000002_12032019.png",
text: 'Product 002',
goldmedal: true,
newitem: false,
newshop: true,
freedelivery: true
}]
}
So you have a product item that looks like this(I assume you can't change that):
{
id: "62276197-6059-4c21-9b40-c5b1d277e85d",
link: "javascript:void(0)",
imgurl: "/img/upload/png/joyacart_000001_12032019.png",
text: 'Product 001',
goldmedal: false,
newitem: true,
newshop: true,
freedelivery: true
},
Let's create an array of keys from that object that tell you if you should show a medal for it:
const medalItems = ['goldmedal', 'newitem', 'newshop', 'freedelivery'];
Now instead of multiple if statements you can iterate over these keys and call createMedal for all these that are true in productItem. Passing that medal key(eg. "goldmedal" or "freedelivery") to createMedal function
for (const medal of medalItems) {
if(productItem[medal]) {
createMedal(medal);
}
}
Now in createMedal you can get src and text based on that medal key, but you'll need to adjust settings accordingly (eg. src for goldmedal should be under plSettings.goldmedalSrc)
function createMedal(medal) {
const src = plSettings[medal + "Src"];
const text = plSettings[medal + "Text"];
...
}
Not perfect because you'll need to keep plSettings in sync with productItems but it should work with your current data structures. And all you need to do to get new one to work is to add it to settings and medalItems array
[![Firefox Console][1]][1]In my Vue app I am trying to use mdb-datatable, the table reads data() and sets the rows accordingly. I am setting the row data programmatically after my data is loaded with Ajax. In one column I need to add a button and it needs to call a function. I am trying to add onclick function to all buttons with "status-button" class but something weird happens.
When I print HtmlCollection it has a button inside, which is expected but I can't reach proceedButtons[0], it is undefined. proceedButtons.length also prints 0 length but I see the button in console.
I also tried to add onclick function but probably "this" reference changes and I get errors like "proceedStatus is not a function" it does not see anything from outer scope.
<mdb-datatable
:data="tableData"
:searching="false"
:pagination="false"
:responsive="true"
striped
bordered/>
export default {
name: "Applications",
mixins: [ServicesMixin, CommonsMixin],
components: {
Navbar,
Multiselect,
mdbDatatable
},
data () {
return {
statusFilter: null,
searchedWord: '',
jobRequirements: [],
applications: [],
options: ['Awaiting', 'Under review', 'Interview', 'Job Offer', 'Accepted'],
tableData: {
columns: [
{
label: 'Name',
field: 'name',
sort: 'asc',
},
{
label: 'Date',
field: 'date',
sort: 'asc'
},
{
label: 'Compatibility',
field: 'compatibility',
sort: 'asc'
},
{
label: 'Status',
field: 'status',
sort: 'asc'
},
{
label: 'Proceed Application Status',
field: 'changeStatus',
}
],
rows: []
}
}
}
fillTable(applications) {
let statusButtonId = 0;
applications.forEach(application => {
this.tableData.rows.push({
name: application.candidateLinkedIn.fullName,
date: this.parseDateFromDateObject(application.applicationDate),
compatibility: this.calculateJobCompatibility(application.candidateLinkedIn.linkedInSkillSet),
status: application.applicationStatus,
changeStatus: '<button type="button" class="btn-indigo btn-sm m-0 status-button"' +
' style="margin-left: 1rem">' +
'Proceed Status</button>',
candidateSkillSet: application.candidateLinkedIn.linkedInSkillSet
});
statusButtonId++;
});
},
addEventListenersToButtons() {
let proceedButtons = document.getElementsByClassName("status-button")
console.log(proceedButtons);
console.log(proceedButtons[0])
console.log(proceedButtons.item(0))
/*
proceedButtons.forEach(button => {
button.addEventListener("click",this.proceedStatus);
});
*/
},
[1]: https://i.stack.imgur.com/zUplv.png
From MDN:
Get the first element with a class of 'test', or undefined if there is no matching element:
document.getElementsByClassName('test')[0]
So undefined means no match, even if length is 0...
Since this is not an array, you do not get out-of-bounds exceptions.
https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName
Regarding Arrays
You can't index the list returned from getElementsByClassName.
You can turn it into an array though, and then index it.
ES6
let proceedButtons = document.getElementsByClassName("status-button")
const arr = Array.from(proceedButtons);
console.log(arr[0]);
Old School
const arr = []
Array.prototype.forEach.call(proceedButtons, function(el) {
arr.push(el);
});
console.log(arr[0]);
I am trying to find a way to handle filtering an array with an array in my Angular 2 app. The data looks like this:
let services = [
{
flags: [
{
action: "Flag One",
completed: true,
},
{
action: "Flag Two",
completed: false,
},
],
ribbons: [
{
action: 'Ribbon One',
active: false,
},
{
action: 'Ribbon Two',
active: true,
},
]
}
]
Now, if I know what item within the second array to target, I can do this:
let filteredServices = services.filter(service => service.flags[0].completed === false);
console.dir(filteredServices);
However, generally I don't know which item within the inner array to target, so how can I write a filter function to iterate over both arrays and filter for the specific item I'm looking for? Would I use a combination of "filter" and "forEach"? Or is there a more succinct way to do this?
You can use filter with some
let filteredServices = services.filter((element) => element.flags.some((subElement) => subElement.completed === false));
Is it possible to load fully custom set of data into select2? I mean I can customize the option text property, can I also do it for id?
The code below works perfect
var dummy = [
{ id: 1, Name: "opt1" },
{ id: 2, Name: "opt2" }
];
$("#myselect").select2({
data: { results: dummy, text: "Name" },
formatSelection: function (item) { return item.Name; },
formatResult: function (item) { return item.Name }
});
However, my data incoming has the id property in caps. It surely would be possible for me to rename these objects' properties iterating through the received data set, yet the amount of data is pretty large and I certainly do not want to slow this simple load down. I'd also love to have these object properties stay.
Long story short, my data is like
var dummy = [
{ ID: 1, Name: "opt1" },
{ ID: 2, Name: "opt2" }
];
Is it possible to define an alternate id key?
yes, there is an option called id
Function used to get the id from the choice object or a string
representing the key under which the id is stored.
$("#myselect").select2({
id: 'ID',
data: { results: dummy, text: "Name" },
formatSelection: function (item) { return item.Name; },
formatResult: function (item) { return item.Name }
});