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
Related
I wrote a query in which I get the semester class, display its values as a name and get its id. Accordingly, when I select the semester I need in the drop-down list, I am given the semester that I chose. But I also need to display its duration in another field, I can do this if I create a ForEach loop and use it to extract this value, but it displays absolutely all the available values, and not the one I need. Tell me how to do it right? For display I use Spring MVC. Now the page looks like this:
I am also attaching the jsp content:
<form:form action="allSemestrsSem" method="get" id="selectSemestr" modelAttribute="semestr">
<tr>
<td style="font-size: large;">Select semester</td>
<td style="padding-left: 50px">
<select name="selectSemestr">
<c:forEach items="${semestr}" var="semestr">
<option value="${semestr.id}">${semestr.name}</option>
</c:forEach>
</select>
</td>
<td style="padding-left: 20px">
<security:authorize access="hasRole('ADMIN')">
<input type="submit" id="button" value="select" /></td>
</security:authorize>
</tr>
<tr height="80px" style="font-size: large; font-weight: bold;">
<td colspan="3">Semester duration:
<c:forEach items="${semestr}" var="semestr"> ${semestr.duration} </c:forEach>
</td>
</tr>
</form:form>
And just in case my controller is:
#RequestMapping(value = "/allSemestrsSem", method = RequestMethod.GET)
public String allSemestrs(#RequestParam(name = "selectSemestr") String selectSemestr, Model model) {
List<Semestr> semestr = service.getSemestr();
model.addAttribute("semestr", semestr);
List<Discipline> allDisciplines = service.getDisciplineSemestrId(Integer.valueOf(selectSemestr));
model.addAttribute("allDisc", allDisciplines);
return "semestr";
}
This get the data from asp.net core webapi which is connected to Microsoft SQL Server. I'm trying to fetch but it returns undefined records in the list
This is Get method:
refreshList(){
this.http.get(this.baseURL).toPromise()
.then(res => this.list = res as PaymentDetail[]);
}
this is the way to make it accessible to html page:
constructor(public service : PaymentDetailService) { }
ngOnInit(): void {
this.service.refreshList();
}
this the way I show in front End:
<div class=col-md-6>
<table class="table">
<thead class="thead-light">
<tr>
<th>Card Owner</th>
<th>Card Number</th>
<th>Exp Date</th>
<th></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let pd of service.list">
<td>{{pd.CardHolder}}</td>
<td>{{pd.CardNumber}}</td>
<td>{{pd.ExpirationdDate}}</td>
<td>
<i class="far fa-trash-alt fa-lg text-danger"></i>
</td>
</tr>
</tbody>
</table>
</div>
The response data is camel case format, so you need change the code below:
<tr *ngFor="let pd of service.list">
<td>{{pd.cardHolder}}</td>
<td>{{pd.cardNumber}}</td>
<td>{{pd.expirationdDate}}</td>
<td>
<i class="far fa-trash-alt fa-lg text-danger"></i>
</td>
</tr>
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
I am using jquery datatables in my MVC ASP.Net application and get an alert warning while the application is running. The alert is "Warning: Scroller requires DataTables 1.10.0 or greater". I have verified that my version of DataTables is 1.10.10 and the DataTables work fairly well except for a few issues.
My issues with DataTables is when pages using it initially load, the number of rows that are supposed to be displayed do not match how many are shown. All rows are shown on a page load. Once I interact with the table, everything is fixed.
I am loading the javascript and css in my BundleConfig.cs file.
One of my views is as follows:
#model IEnumerable<Q5.ViewModels.ProjectVM>
#{
ViewBag.Title = "Projects";
}
<h2>Projects/Deals</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table table-striped table-hover display" id="projects" cellspacing="0">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
#Html.DisplayName("Last Updated")
</th>
<th>
#Html.DisplayName("Sales Person")
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.ActionLink(item.Name, "ProjectProfile", new { id = item.Id })
</td>
<td>
#Html.DisplayFor(modelItem => item.LastUpdated)
</td>
<td>
#Html.DisplayFor(modelItem => item.AssignedToUserName)
</td>
</tr>
}
</tbody>
</table>
<script>
$(document).ready(function () {
$('#projects').DataTable();
})
</script>
You could have the table refreshed after load:
$('#example').dataTable( {
"initComplete": function(settings, json) {
alert( 'DataTables has loaded.' );
$('#example').dataTable().ajax.reload( null, false );
}
} );
This may not be 100% syntax, just typed off the cuff. I seem to remember having to do this for a project, but the details escape me. I never could figure out why it happened so I slapped this band aid on it.
//AJAX Webservice Call
ManualRegDiseaseData = $.parseJSON(rows.d);
var VM = new testView(ManualRegDiseaseData);
ko.applyBindings(VM);
var testView = function (DiseaseData) {
var self = this;
self.disease = ko.observableArray();
self.benefitData = ko.observableArray();
var sampleBenefit = [{ "Benefit": "Room", "Detail": "Ordinary", "Desc": "not herbal", "TotalDays": "2", "Remaining": "1000", "Claimed": "400", "Approved": "350", "Excess": "50" },
{ "Benefit": "Medicine", "Detail": "All", "Desc": "herbal", "TotalDays": "1", "Remaining": "2000", "Claimed": "800", "Approved": "600", "Excess": "100" }];
$.each(sampleBenefit, function (x, rowType) {
var obj = new BenefitObject();
obj.Benefit(rowType.Benefit);
obj.Detail(rowType.Detail);
obj.Desc(rowType.Desc);
obj.TotalDays(rowType.TotalDays);
obj.Remaining(rowType.Remaining);
obj.Claimed(rowType.Claimed);
obj.Approved(rowType.Approved);
obj.Excess(rowType.Excess);
self.benefitData.push(obj);
})
$.each(DiseaseData, function (x, rowType) {
var obj = new DiseaseObject();
obj.DiseaseCode(rowType.DiseaseCode);
obj.DiseaseName(rowType.DiseaseName);
self.disease.push(obj);
})
}
<table id="tblDisplayBenefit" class="">
<thead>
<tr>
<th>No.</th>
<th>Benefit </th>
<th>Detail </th>
<th>Description </th>
<th>Total Days </th>
<th>Remaining Inner Limit </th>
<th>Claimed </th>
<th>Approved </th>
<th>Excess </th>
<th>Reduce Max Limit </th>
</tr>
</thead>
<tbody data-bind="foreach: benefitData">
<tr>
<td data-bind="value: Benefit"></td>
<td data-bind="value: Detail"></td>
<td data-bind="value: Desc"></td>
<td data-bind="value: TotalDays"></td>
<td data-bind="value: Remaining"></td>
<td data-bind="value: Claimed"></td>
<td data-bind="value: Approved"></td>
<td data-bind="value: Excess"></td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="6" style="text-align: right">Total</td>
<td>Total Claimed</td>
<td>Total Approved</td>
<td>Total Excess</td>
</tr>
</tfoot>
</table>
Those are my JS snippet code and my html, the problem is, I can not data bind the sample JSON variable into my table. It seems I can not push my data into benefitData object.
I have been doing console.log the rowType, the Json data is readable through the console.log.
I dont know, this must be a simple data binding, yet I dont know where is the fault part.
I cant figure this out.
Thanks in advance for the suggestion!
Use text binding instead of value for text int the table cells:
<td data-bind="text: Benefit"></td>
<td data-bind="text: Detail"></td>
<td data-bind="text: Desc"></td>
<td data-bind="text: TotalDays"></td>
<td data-bind="text: Remaining"></td>
<td data-bind="text: Claimed"></td>
<td data-bind="text: Approved"></td>
<td data-bind="text: Excess"></td>
Js Fiddle
According to knockout documentation
The value binding links the associated DOM element’s value with a
property on your view model. This is typically useful with form
elements such as input, select and textarea.
In other words it works with form elements and makes two-way binding, so when you change the value knockout automatically updates your ViewModel.
On the other hand, text binding
Typically this is useful with elements like span or em that
traditionally display text, but technically you can use it with any
element.
So you should use text binding here, because <td> element has static content.