How to bind server generated html data into knockout model attribute? - javascript

I want to bind back server generated html into knockout model. Is there any manner to do it?
<table>
<tr data-bind="with: dataList">
<td data-bind="text: Name">
Name
</td>
<td data-bind="text: Text">
Text
</td>
</tr>
<tr data-bind="with: dataList">
<td data-bind="text: Name">
Name2
</td>
<td data-bind="text: Text">
Text2
</td>
</tr>
</table>
Stuff like this...

The dataList property of the object you bound to view will contain all the data you are expecting.
You should use ko.mapping.toJS() to convert an observable view model to a raw view model.

Related

Can you insert HTML in jQuery without string?

So the normal way to insert a HTML element is by writing
$("#addingRow").before(`
<tr id="customer`+customer.id+`">
<td class="id">`+customer.id+`
</td>
<td class="firstname"><input type="text" value="`+customer.firstname+`"/>
</td>
<td class="lastname"><input type="text" value="`+customer.lastname+`"/>
</td>
<td class="email"><input type="text" value="`+customer.email+`"/>
</td>
<td>
<button onclick="onClickSave(`+customer.id+`)">Save</button>
<button onclick="onClickDelete(`+customer.id+`)">Delete</button>
</td>
</tr>
`)
or some function similar to this like (prepend, before, ...)
Is there some way to insert the HTML element without using the string tags?
Like in Angular where you only have to write *ngFor inside the HTML code.

Filter in more than 1 column of a table in angular js

I am trying to add a filter on more than one column of a table which is being populated by ng-repeat directive.
<tr ng-repeat="descriptiveField in vm.descriptiveFieldList|filter:{name:vm.searchText}" ng-class-even="'even-bgcolor'">
<td ng-bind=descriptiveField.name></td>
<td ng-bind="descriptiveField.fieldDescription></td>
<td style="text-align: left" ng-bind=descriptiveField.source></td>
</tr>
I have search box as
<input type="text" ng-model="vm.searchText" class="search-input"/>
The filter is getting applied on Name only. I would to search on 2 columns name and source. How to do that?
Use $ to filter any fields (same level or deeper):
<tr ng-repeat="descriptiveField in vm.descriptiveFieldList | filter:search:strict}" ng-class-even="'even-bgcolor'">
<td ng-bind=descriptiveField.name></td>
<td ng-bind="descriptiveField.fieldDescription></td>
<td style="text-align: left" ng-bind=descriptiveField.source></td>
</tr>
<input type="text" ng-model="search.$" class="search-input"/>

Radio button is selecting wrongly from data list in angular js and dynamic validation

I have data list which will display in the form of multiple radio buttons . each row will have 3 fields .
ex: row1:abc , 123 , xyz
row2: xyz , 145 , xyz
now when i select radio button in first row it is selecting second row . How to make that radio row unique ?
<label ng-repeat="list in data">
<table>
<tr
<td rowspan="2" >
<input type="radio" name="select" />
</td>
<td>
{{list.name}}
</td>
<td>
{{list.number}}
</td>
</tr>
<tr>
<td>
{{list.value}}
</td>
</tr>
</table>
Also how do I validate these fields , if they are comming as null I have display error message since it is dynamic data and this page is read only page .
Thanks in advance
For the null validation you can use a conditional in a ng-bind directive and for selecting different values you need a different name for each row
<label ng-repeat="list in data">
<table>
<tr
<td rowspan="2" >
<input type="radio" ng-attr-name="{{'select' + list.number}}" />
</td>
<td ng-bind="{{list ? list.number: 'error name'}}">
</td>
<td ng-bind="{{list ? list.number: 'error number'}}">
</td>
</tr>
<tr>
<td ng-bind="{{list ? list.value : 'error value'}}">
</td>
</tr>
</table>
I'm not sure if the ng-attr-name will work :( please let me know if this works
In html
<table>
<tr ng-repeat="data in list">
<td>
<input type="radio" ng-model="val.value" value="{{$index}}">
</td>
<td>
<span ng-show="data.name">{{data.name}}</span>
<span ng-hide="data.name">Error in name</span>
</td>
<td>
<span ng-show="data.number">{{data.number}}</span>
<span ng-hide="data.name">Error in number</span>
</td>
</tr>
</table>
In controller
$scope.val ={} // take this object this will store current row number
//$scope.val.value // contain row number
var data = $scope.list[$scope.val.value] // this will give u data at that row

Best practice for Angular ng-repeat with nested data

I have the following code that I admit looks pretty gross. Anyone have a suggest for cleaning it up and making it a bit more scalable without using nested tables?
<tr data-ng-repeat="data in displayData">
<td data-ng-show="data.name">
{{data.name}}
</td>
<td data-ng-show="data.cols[0]" data-ng-repeat="value in data.cols[0]">
{{value}}
</td>
<td data-ng-show="data.cols[1]" data-ng-repeat="value in data.cols[1]">
{{value}}
</td>
<td data-ng-show="data.cols[2]" data-ng-repeat="value in data.cols[2]">
{{value}}
</td>
<td data-ng-show="data.cols[3]" data-ng-repeat="value in data.cols[4]">
{{value}}
</td>
<td data-ng-show="data.cols[4]" data-ng-repeat="value in data.cols[3]">
{{value}}
</td>
</tr>
I think this is what you're trying to achieve, but I'm not entirely sure by looking at your code.
<tr data-ng-repeat="data in displayData">
<td data-ng-show="data.name">
{{data.name}}
</td>
<td data-ng-show="column" data-ng-repeat="column in data.cols">
{{ column.value }}
</td>
</tr>
What I did was actually flatten data.cols to one array in the controller. Something like this:
var merged = [].concat.apply([], row.cols);
row.cols = merged;
$scope.displayData.push(row);

Knockout.js -- understanding foreach and with

I've been going through the learn.knockout.js tutorials and been experimenting. Can someone explain why this works [Tutorial: Single page applications, Step 2] (using with: chosenFolderData and foreach: mails):
<!-- Mails grid -->
<table class="mails" data-bind="with: chosenFolderData">
<thead><tr><th>From</th><th>To</th><th>Subject</th><th>Date</th></tr></thead>
<tbody data-bind="foreach: mails">
<tr>
<td data-bind="text: from"></td>
<td data-bind="text: to"></td>
<td data-bind="text: subject"></td>
<td data-bind="text: date"></td>
</tr>
</tbody>
</table>
but not this (using just foreach: chosenFolderData.mails):
<!-- Mails grid -->
<table class="mails">
<thead><tr><th>From</th><th>To</th><th>Subject</th><th>Date</th></tr></thead>
<tbody data-bind="foreach: chosenFolderData.mails">
<tr>
<td data-bind="text: from"></td>
<td data-bind="text: to"></td>
<td data-bind="text: subject"></td>
<td data-bind="text: date"></td>
</tr>
</tbody>
</table>
I suspect it's because while chosenFolderData is observable, chosenFolderData.mails is not. Can anyone tell me for certain?
Many thanks!
-- Ralph
Because you are not actually accessing the property you want with the way it is written. In the model chosenFolderData is an observable and must be called like a method to retrieve the value. To provide the functionality without using with (and I suggest not using with where high performance is necessary because of the overhead)...
<tbody data-bind="foreach: chosenFolderData().mails">

Categories

Resources