navigating array inside a collection and nested templates in meteor - meteor

I am playing around with meteor and trying to create a simple quiz application using the same. I have setup my questions collection this way:
{question: "Why did the chicken cross the road??", choices: ["To eat", "To die", "It depends", "There is no chicken"], correctAnswer:2, number : 1},
{question: "Who was the first man to step on moon's surface?", choices: ["Yo Yo Honey Singh", "Neil Armstrong", "Buzz Eldrin", "Rakesh Sharma"], correctAnswer:1, number : 2},
{question: "Where is Timbuktu? ", choices: ["Asia", "There is no such place", "Africa", "Europe"], correctAnswer:2, number : 3},
{question: "Who said 'there is no pill'?", choices: ["Morpheus", "Mr. Anderson", "Neo", "Yoda"], correctAnswer:0, number : 4},
{question: "What is the one thing that saved Arthur Dent's life multiple times?", choices: ["The bugblatter beast of Tral", "Ford Perfect", "A towel", "The babel fish"], correctAnswer:2 , number : 5}
I am able to get the question from the collection but struggling with getting the options for each question (which are stored in an array as shown above). I created two templates, one for the question stem and the second one for the choices. The options template is nested inside the question template like so:
<template name="question">
<p>{{ currentQuestion.question }}</p>
<form>
{{ #each currentQuestion.choices }}
<div class="radio answers">
{{> choices}}
</div>
{{ /each }}
</form>
</p>
</template>
<template name="choices">
<input type="radio" name="answer" id="{{ choice }}"><label for="{{ choice }}">{{ choice }}</label><br>
</template>
Obviously this is not working. Now my questions are:
Is this the best way to setup my collection of question?
How do I setup my nested templates to navigate and display the array of choices in my collection?
Thanks in advance. Looking forward to some solutions for this.
Cheers..

<template name="questions">
{{#each questions}}
{{> question}}
{{/each}}
</template>
<template name="question">
<p>{{ question }}</p>
<form>
{{ #each choices }}
<div class="radio answers">
{{> choices}}
</div>
{{ /each }}
</form>
</template>
<template name="choices">
<input type="radio" name="answer" id="{{ this }}"><label for="{{ this }}">{{ this }}</label><br>
</template>
See working sample in meteorpad

Related

Meteor - Blaze easy-search template - how to insert input field attributes into template?

So I have an easy-search template:
<template name="searchBox">
<div class="">
{{> EasySearch.Autosuggest index=PlayersIndex }}
</div>
</template>
And I'd like to make the input field look like this (have the following attributes):
<input
type="text"
placeholder="Type to add new player"
ref="textInput"
/>
I've tried adding the attributes to the argument but that doesn't seem to work:
{{> EasySearch.Autosuggest index=PlayersIndex type="text"}}
Any ideas how to achieve this?
Just add attributes property in your HTML:
{{> EasySearch.Input index=index attributes=inputAttributes}}
And in your JS, fill it with your needed data:
`Template.leaderboard.helpers({
inputAttributes: function () {
return { 'class': 'easy-search-input', 'placeholder': 'Start searching...' };
}
)}
`
I was able to find the answer by looking at this repo, so make sure to check github repos as they might contain helpful examples. ;)

Meteor: Custom AutoForm with array of objects in afEachArrayItem blocks

I'm working on dictionary app, and schema have a nested structure.
articles (collection)
-words (array of objects {"note", "word"} )
-translations (array of objects {"translation", "examples"} )
--examples (array of objects {"example", "translation"} ) that means
examples of word usage with it's translation.
The {{> quickForm collection=articles ... }} are working fine, but I want to change template and functionality by some conditions...
I tried to use
{{#autoForm collection=articles id="insertArticleForm" class="article-form" }}
{{#afEachArrayItem name='words'}}
{{> afFieldInput name=this.current.note placeholder='schemaLabel' class="note"}}
{{> afFieldInput name=this.current.word placeholder='schemaLabel' class="word"}}
<button type="button" class="autoform-remove-item"><span class="glyphicon glyphicon-remove"></span></button>
{{/afEachArrayItem}}
<button type="button" class="autoform-add-item" data-autoform-field="words"><span class="glyphicon glyphicon-plus"></span></button>
{{/autoForm}}
But it doesn't work.
It looks like this old issue: Meteor: Custom AutoForm with array of objects
but it seems after some recent updates of Meteor/Autoform, this syntax doesn't work.... and author of plugin doesn't answer on issues for months (
When I changed {{> afFieldInput name=this.current.note }} to {{> afFieldInput name='words.$.note' }} it seems like working , form appears with all need fields, but nothing are submit on the server. Even in this simple example, without nested fields...

Go 'up' scope in meteor blaze?

How can I use a variable in a scope up from the current scope in Blaze?
For example:
<template name="userLayoutEditCreate">
{{#each findUser id}}
<h3>I am a single user (edit/create)</h3>
<h3>{{id}}</h3>
<form action="/" method="post">
<fieldset>
<!-- Primary instruments multi-select -->
<div class="form-group">
<label class="control-label" for="playerPrimaryInstrument">Primary instruments</label>
<div class="controls text-left">
<select id="playerPrimaryInstrument" name="playerPrimaryInstrument">
{{#each instruments}}
<option value="{{name}}" {{#if equals primary_instrument name}} selected="selected" {{/if}}>{{name}}</option>
{{/each}}
</select>
</div>
</div>
</fieldset>
</form>
{{/each}}
</template>
The if statement does not run within the each block. But it does run outside of the each block (I have defined the helper).
The error I get looks like this.
Reactive HTML attributes must either have a constant name or consist of a single {{helper}} providing a dictionary of names and values. A template tag of type BLOCKOPEN is not allowed here.
==== EDIT ====
Even using the '../' scope definition didn't work in this case. What DID work was putting the expression inside the value of the selected attribute. I'm not sure why that is, please let me know if you have any idea?
The solution:
{{#each instruments}}
<option value="{{name}}" selected="{{#if equals name ../primary_instrument}} selected {{/if}}">{{name}}</option>
{{/each}}
Try this:
{{#if equals ../primary_instrument name}}
{{/if}}

How do I seperate the label and field in twig forms?

I want to be able to apply some bootstrap formatting on these fields and labels but I don't want all the fields displayed and I know using widget renders the rest of the fields and labels so what can I use in lieu? I tried
{{ form_start(edit_form, {'attr': {'novalidate': 'novalidate'}}) }}
{{ form_row(edit_form.orgName, {'label_attr': {'class': 'col-md-2'}}, {'label': 'Organization Name'}, {'attr': {'class': 'col-md-4'}}) }}
// blah blah more labels and fields
{{ form_end(edit_form) }}
This generates:
<div class="form-group'">
<div><label class="col-md-2 required" for="company_nameofbundleorg_orgName">Org name</label><input type="text" id="company_nameofbundle_org_orgName" name="company_nameofbundle_org[orgName]" required="required" value="Computation Directorate" /></div>
</div>
Update: I tried this:
{{ form_row(edit_form.orgName, { 'label': 'Organization Name:'
,'label_attr': {'class': 'col-md-2'}
,'attr': {'class': 'col-md-4'}}) }}
I guess putting the "label" before the "label_atrr" matters. But why am I getting my class as "col-md-2 required".
<div class="form-group'">
<div><label class="col-md-2 required" for="company_nameofbundle_org_orgName">Organization Name:</label><input type="text" id="company_nameofbundle_org_orgName" name="company_nameofbundle_org[orgName]" required="required" class="col-md-4" value="Computation Directorate" /></div>
</div>
As you can see it's not applying it to the <div> does not get applied. Any ideas?
This might not be the best solution. I still think modifying the "form_div_layout.html.twig" is probably the best stratgey. A faster solution in my case is to just put
<div class="hidden">
{{ form_widget(edit_form.orgFax) }}
</div>
to not show the one field I do not want to display. If your interested in modifying the "form_div_layout.html.twig" it is located in /vendor/symfony/symfony/src/Symfony/Bridge/Twig/Resources/views/Form/ and here is a good source for modifying it.

How can I avoid duplicate templates in Meteor?

So I'm building my first app with meteor, and I feel like I'm repeating myself with my templates more than I should be.
I have multiple parent views, an example of which is the user contacts view, and the add group members view. (simplified examples below.)
<template name="GroupMembers">
{{#each contacts}}
{{> contact }}
{{/each}}
</template>
<template name="contacts">
{{#each contacts}}
{{> contact }}
{{/each}}
</template>
<template name="contact">
//... single contact template stuff
</template>
When the contact is displayed in the contacts list, I want to display a remove from contacts link in the single contact template, but in the group members list I'd like an 'add to group' link in its place. I know I could probably achieve this with either session variables or by invoking the iron-router controller obj, but I'd like to know if there is a simple way to do this in the template helper(s). Or put another way can these template partials become context aware?
Any help would be great.
Thanks.
I would solve it this way:
<template name="GroupMembers">
{{#each contacts}}
{{> contact groupMembers=true}}
{{/each}}
</template>
<template name="contacts">
{{#each contacts}}
{{> contact }}
{{/each}}
</template>
<template name="contact">
<p>
{{#if groupMembers}}
{{../name}}
<button>add to group</button>
{{else}}
{{name}}
<button>delete</button>
{{/if}}
</p>
</template>
Live demo: http://meteorpad.com/pad/LDTvHC787kJ6e9JQA/Leaderboard

Resources