I have code like following:
in test.html
<template name="main">
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<td>Name</td>
<td>City</td>
<td>Email</td>
</tr>
</thead>
<tbody>
{{#each users}}
<tr>
<td>{{names}}</td>
<td>{{city}}</td>
<td>{{email}}</td>
</tr>
{{/each}}
<tr>
<td><input type="text" name="names" id="names" value=""></td>
<td><input type="text" name="city" id="city" value=""></td>
<td><input type="text" name="email" id="email" value=""></td>
</tr>
</tbody>
</table>
<button class="btn" id="add">Add</button>
</template>
in test.js
UserInfo = new Meteor.Collection('users');
if (Meteor.isClient) {
Template.main.users=function() {
return UserInfo.find();
}
}
Template.main.events({
'click #add': function () {
var names = $('#names').val();
var city = $('#city').val();
var email = $('#email').val();
UserInfo.insert({names:names,city:city,email:email});
}
});
After clicking on add button i want to take input data(name, location and email) and insert data in to the table but it is showing some error like "template not define".
You should move the Template code inside client block and also creating individual helpers is deprecated. Use helpers block instead.
if (Meteor.isClient) {
Template.main.helpers({
users: function() {
return UserInfo.find();
}
});
Template.main.events({
'click #add': function () {
var names = $('#names').val();
var city = $('#city').val();
var email = $('#email').val();
UserInfo.insert({names:names,city:city,email:email});
};
});
}
Related
I'm fairly new to meteor and I'm trying to iterate over a cursor using #each to populate a table. Here's my code:
<template name="choral">
<div class="container" style="padding-top: 25px">
<div class="table-responsive">
<form id="orderForm">
<table class="table table-borderless table-dark">
<thead class="thead-light">
<tr>
<th>Title:</th>
<th>See the Music:</th>
<th>Hear the Music:</th>
<th>Format:</th>
<th>Price (per copy):</th>
<th>Quantity:</th>
</tr>
</thead>
<tbody>
{{#each piece in pieces}}
<tr>
<td id="name">{{piece.name}}</td>
<td id="pdf">PDF</td>
<td id="audio">AUDIO</td>
<td id="format">FORMAT</td>
<td id="price">{{piece.score}}</td>
<td id="qty"><input type ="number" name ="quantity" min="5"></td>
</tr>
{{/each}}
</tbody>
<tfoot>
<tr>
<td colspan="5"></td>
<td><button class="button" type ="submit">Add to Cart</button></td>
</tr>
</tfoot>
</table>
</form>
</div>
</div>
my js.
Template.choral.helpers({
pieces: function(){
return choralm.find({});
}
});
I'm outputting a blank row between the #each tag. I publish the collection server side and subscribe. I'm just not sure where to look. Any ideas?
My publishment and subscription:
Meteor.publish('choralList', function() {
return choralm.find();
});
Template.choral.onCreated( function(){
Meteor.subscribe('choralList');
});
As far as I can see you are subscribing to your data but you are not "telling" your template, that the subscription is finished and it should redraw.
Therefore your template immediately renders while the subscription is ongoing and thus uses the yet empty collection data.
In order to inform your template that data has been updated you can use it's internal Tracker and store the information in a reactive data-source (for my example I use ReactiveDict instead of ReactiveVar).
import { ReactiveDict } from 'meteor/reactive-dict';
Template.choral.onCreated( function (){
// inside onCreated, this refers to the
// current template instance
const instance = this;
// let's attach a ReactiveDict to the instance
instance.state = new ReactiveDict();
// use the internal Tracker
instance.autorun(() => {
// subscribe and store a flag, once ready
const choralListSub = Meteor.subscribe('choralList');
if (choralListSub.ready()) {
instance.state.set('subscriptionComplete', true);
}
});
});
Next you add a helper, that returns the reactive value for 'subscriptionComplete':
Template.choral.helpers({
pieces(){
return choralm.find({});
},
subscriptionComplete() {
// we use 'state', our ReactiveDict,
// which we added as prop in onCreated
return Template.instance().state.get('subscriptionComplete');
}
});
And finally we let our template draw the data, once our subscription is complete. Until the subscription is complete (note the {{else}} block), we display a message about the loading status:
<template name="choral">
<div class="container" style="padding-top: 25px">
{{#if subscriptionComplete}}
<div class="table-responsive">
<form id="orderForm">
<table class="table table-borderless table-dark">
<thead class="thead-light">
<tr>
<th>Title:</th>
<th>See the Music:</th>
<th>Hear the Music:</th>
<th>Format:</th>
<th>Price (per copy):</th>
<th>Quantity:</th>
</tr>
</thead>
<tbody>
{{#each piece in pieces}}
<tr>
<td id="name">{{piece.name}}</td>
<td id="pdf">PDF</td>
<td id="audio">AUDIO</td>
<td id="format">FORMAT</td>
<td id="price">{{piece.score}}</td>
<td id="qty"><input type ="number" name ="quantity" min="5"></td>
</tr>
{{/each}}
</tbody>
<tfoot>
<tr>
<td colspan="5"></td>
<td><button class="button" type ="submit">Add to Cart</button></td>
</tr>
</tfoot>
</table>
</form>
</div>
{{else}}
<div>Loading template...</div>
{{/if}}
</div>
</template>
Related resources
TemplateInstance.autorun
http://blazejs.org/api/templates.html#Blaze-TemplateInstance-autorun
https://docs.meteor.com/api/tracker.html
Reactive stores
https://guide.meteor.com/data-loading.html#stores
Subscription readyness
https://guide.meteor.com/data-loading.html#readiness
Helpers
http://blazejs.org/guide/spacebars.html#Built-in-Block-Helpers
Controller:
#RequestMapping(value = { "/download-answer1-{userId}" }, method = RequestMethod.POST)
public String downloadAnswers1(#PathVariable int userId, HttpServletRequest request, HttpServletResponse response) throws IOException {
try {
String []docId1 = request.getParameterValues("doc-id");
for(String docId : docId1) {
UserDocument document = userDocumentService.findById(Integer.valueOf(docId));
response.setContentType(document.getType());
response.setContentLength(document.getContent().length);
response.setHeader("Content-Disposition","attachment; filename=\"" + document.getName() +"\"");
FileCopyUtils.copy(document.getContent(), response.getOutputStream());
System.out.println("call me");
response.flushBuffer();*/
}
}catch(Exception e) {}
return "redirect:/download-answer-"+userId;
}
View (downloadAnswer.jsp):
<form action="${pageContext.request.contextPath}/download-answer1-${userId}" method="post">
<div class="panel-heading"><span class="lead">List of Documents </span><%-- --%><button onclick="return confirm('Are you sure')">download</button><!-- --></div>
<table class="table table-hover">
<thead>
<tr>
<th scope="col" class="slctDlt" ><input type="checkbox" id="selectAll" ></th>
<th>No.</th>
<th>File Name</th>
<th>Type</th>
<th>Description</th>
<th width="100"></th>
<th width="100"></th>
</tr>
</thead>
<tbody>
<c:forEach items="${documents}" var="doc" varStatus="counter">
<tr id=''>
<td><input type="checkbox" class="dltCheck" name="doc-id" value="${doc.id}"></td>
<td>${counter.index + 1}</td>
<td>${doc.name}</td>
<td>${doc.type}</td>
<td>${doc.description}</td>
<td><a href="<c:url value='/download-answer1-${user.id}-${doc.id}' />" class="btn btn-success custom-width" >download</a></td>
</tr>
</c:forEach>
</tbody>
</table>
</form>
I have already done lot of thing but all time it's download one files at time i.e. first file.
HTTP protocol doesn't support responding with multiple files. It is not possible to perform this. If you need to iterate, the view would have to request multiple times and probably your controller servlet would have to be stateful for you to keep the iteration index.
I integrated HDIV and Spring MVC. Now I have a form on which there are three dropdown lists contract, taskorder and subtask. The select change of contract will update the content of taskorder dropdown list via ajax and then the select change of the task order will update the content of dropdown list subtask via ajax. The form looks like this:
<c:url var="url" value="/admin/user/newstafftask" >
<c:param name="_MODIFY_HDIV_STATE_" value="${taskOrder.id}" />
</c:url>
<form:form action="${url}" commandName="newRequestStaffTasks">
<form:hidden path="subId" />
<table >
<tr>
<td> <label>Contract </label></td>
<td>
<form:select path="newRequestStaffContract.id">
<option></option>
<form:options items="${contractList}" itemValue="id" itemLabel="contract.contractNbr" />
</form:select>
</td>
</tr>
<tr>
<td> <label>Task Order </label></td>
<td>
<form:select path="taskOrder.id">
</form:select>
</td>
</tr>
<tr>
<td> <label>SubTask Code </label></td>
<td>
<form:select path="subtask.subTaskId">
<option></option>
</form:select>
</td>
</tr>
</table>
</form:form>
When I tried to submit the form, I got the error message "INVALID_PARAMETER_NAME" about the taskOrder.id. I understand the problem is the values of two dropdown lists were updated on the client side.I tried _MODIFY_HDIV_STATE_, but it did not work with this case. So I am not sure how to deal with it now. Please help. Thanks.
Update 1
I already exclude the Ajax request from the HDIV validation. Below is the code snippet that update taskOrder list when the contract select change:
$(".modal-body").on("change", "#newRequestStaffContract\\.id", function() {
getTaskOrderByContract($(this));
});
function getTaskOrderByContract(o) {
contractId = o.val();
if (contractId) {
$.get("../../ajax/getTaskOrderByContract", {
contractId : contractId
}
, function(data) {
var options = '<option value=""></option>';
for (var i = 0; i < data.length; i++) {
options += '<option value="' + data[i].id + '">' +data[i].taskNum+ '</option>';
}
$('#taskOrder\\.id').html(options);
});
};
};
I am all new to Durandal and have been playing around with it for a few hours now. It seems very promising - but now I have run into a problem, I cannot figure out - and cannot find a solution with Google.
I have a view with three tables of data - creditCardLines, cashLines and drivingReimbursementLines. They fetch data from three different data sources - and the user can add new lines to cashLines and drivingReimbursementLines (left out the forms).
Problem: In the viewmodel, I can easily bind a list for data to the first foreach - but I cannot figure out how to bind data to the second and third.
In the activate function I make an ajax call to my server API to get the data for the first foreach - and then returns the promise, when this finishes. How do I get data for the second and third foreach here?
ViewModel:
define(function () {
var submit = function () {
this.displayName = 'Expenses';
this.creditCardLines = ko.observableArray();
var me = this;
this.activate = function () {
return $.get('/submit/GetCreditCardLines').then(function (creditCardLines) {
me.creditCardLines(creditCardLines.Data);
});
};
};
return submit;
});
View:
<section>
<h2 data-bind="html:displayName"></h2>
<h3>CreditCard lines</h3>
<table class="table">
<tbody data-bind="foreach: creditCardLines">
<tr>
<td class="date" data-bind="text: Date"></td>
<td data-bind="text: Description"></td>
<td data-bind="text: Amount"></td>
<td><input type="checkbox" data-bind="checked: ApprovedEmployee" /></td>
</tr>
</tbody>
</table>
<h3>Cash lines</h3>
<table class="table">
<tbody data-bind="foreach: cashLines">
<tr>
<td class="date" data-bind="text: Date"></td>
<td data-bind="text: Description"></td>
<td data-bind="text: Amount"></td>
</tr>
</tbody>
</table>
<!-- TODO: Generate form to add new lines -->
<h3>Driving reimbursement lines</h3>
<table class="table">
<tbody data-bind="foreach: drivingReimbursementLines">
<tr>
<td class="date" data-bind="text: Date"></td>
<td data-bind="text: Description"></td>
<td data-bind="text: Distance"></td>
<td data-bind="text: Rate"></td>
<td data-bind="text: Amount"></td>
</tr>
</tbody>
</table>
<!-- TODO: Generate form to add new lines -->
<!-- Approve and save all lines as a quote with lines -->
<input type="submit" value="Submit quote" />
</section>
This is how I've been dealing with multiple jQuery deferred calls in my view models:
return $.when(
$.get('/submit/GetCreditCardLines'),
$.get('/submit/GetCashLines'),
$.get('/submit/GetReimbursementLines'))
.then(function (creditCardLines, cashLines, reimbursementLines)
{
processCreditCardLines(creditCardLines);
processCashLines(cashLines);
processReimbursementLines(reimbursementLines);
})
.fail(function (status)
{
// Do whatever you need to if it fails
});
You don't need the process methods if you don't want them, but if you're doing anything complicated, I think it's neater to have them.
You should check out BreezeJS. It has an option to make a single Ajax call to pull multiple lookups.
Take a look at the BreezeJS docs for a detailed explanation: http://www.breezejs.com/documentation/lookup-lists
I suppose there are people who encountered underscore problem, so I found something here:
Using Underscore.js with ASP.NET
and the solution was to add:
_.templateSettings = {interpolate : /\{\{(.+?)\}\}/g, // print value: {{ value_name }}
evaluate : /\{%([\s\S]+?)%\}/g, // excute code: {% code_to_execute %}
escape : /\{%-([\s\S]+?)%\}/g}; // excape HTML: {%- <script> %} prints <script>
to underscore.js
so I opened underscore.js and found the _.templateSettings section, and replaced with the above solution, still with no luck.
Is there anywhere that I'm missing? here's my code looks like:
<table class="table">
<thead>
<tr>
<th></th>
<th>#</th>
<th>Keyword</th>
<th>Corresponding Field</th>
<th>Add</th>
</tr>
</thead>
<tbody>
<% _.each(keywords, function(keyword, key, list) { %>
<tr>
<td><label class="checkbox"><input type="checkbox" /></label></td>
<td><%= key + 1 %></td>
<td><input name="keywords[<%= key %>][keyword]" class="input-medium keyword-name" type="text" value="<%= keyword.name %>" /></td>
<td>
<select class="keyword-field">
<% _.each(fields, function(field, key, list) { %>
<option name="keywords[<%= key %>][field]" value="<%= field.id %>" <% if (keyword.fieldId == field.id) { %>selected<% } %>><%= field.name %></option>
<% }); %>
</select>
</td>
<td class="align-right">Define</td>
</tr>
<% }); %>
</tbody>
</table>
so this is what I end up doing:
<script type="text/javascript">
$(document).ready(function ()
{
_.templateSettings = {
interpolate: /\<\#\=(.+?)\#\>/g,
evaluate: /\<\#(.+?)\#\>/g
};
});
</script>
above code inside html head
and change to <# ... #>
so this is what my code ends up:
<tbody>
<# _.each(keywords, function(keyword, key, list) { #>
<tr>
<td><label class="checkbox"><input type="checkbox" /></label></td>
<td><#= key + 1 #></td>
<td><input name="keywords[<#= key #>][keyword]" class="input-medium keyword-name" type="text" value="<#= keyword.name #>" /></td>
<td>
<select class="keyword-field">
<# _.each(fields, function(field, key, list) { #>
<option name="keywords[<#= key #>][field]" value="<#= field.id #>" <# if (keyword.fieldId == field.id) { #>selected<# } #>><#= field.name #></option>
<# }); #>
</select>
</td>
<td class="align-right">Define</td>
</tr>
<# }); #>
</tbody>