Reputation: 613
I have been trying to remove the formulation elements with the 'Delete comp' link, but I'm not sure why it's not working. Also, the 'Add another composition' link is working once, but not multiple times. I'm working with Knockout.js and any explanation why this is not working will be greatly helpful.
$( document ).ready(function() {
var initialData = [
];
var brandNamesModel = function(brandNames) {
var self = this;
self.brandNames = ko.observableArray(ko.utils.arrayMap(brandNames, function(drug) {
return { brandName: drug.brandName, formulations: ko.observableArray(drug.formulations), compositions: ko.observableArray(drug.compositions) };
}));
self.addBrandName = function() {
self.brandNames.push({
brandName: "",
formulations: ko.observableArray(),
compositions: ko.observableArray()
});
};
self.removeBrandName = function(drug) {
self.brandNames.remove(drug);
};
self.addFormulations = function(drug) {
drug.formulations.push({
compositions: ko.observableArray()
});
};
self.removeFormulations = function(formulation) {
$.each(self.brandNames(), function() { this.formulations.remove(formulation) })
};
self.addComposition = function(drug) {
drug.compositions.push({
type: "",
number: ""
});
};
self.removeComposition = function(composition) {
$.each(self.brandNames(), function() { this.compositions.remove(composition) })
};
self.save = function() {
self.lastSavedJson(JSON.stringify(ko.toJS(self.brandNames), null, 2));
};
self.lastSavedJson = ko.observable("")
};
ko.applyBindings(new brandNamesModel(initialData));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div class='container'>
<h2>brandNames</h2>
<div>
<table>
<tr>
<th>Brand name</th>
<th>formulations</th>
</tr>
<tbody data-bind="foreach: brandNames">
<tr>
<td>
<input data-bind='value: brandName' />
<div><a href='#' data-bind='click: $root.removeBrandName'>Delete brand name</a></div>
</td>
<td>
<table>
<tbody data-bind="foreach: formulations">
<tr>
<td><label>Formulation</label></td>
<td><select>
<option>Tablet</option>
<option>Syrap</option>
</select>
</td>
<td><a href='#' data-bind='click: $root.removeFormulations'>Delete</a></td>
<td>
<table>
<tbody data-bind="foreach: compositions">
<tr>
<td><input data-bind='value: type' /></td>
<td><input data-bind='value: number' /></td>
<td><a href='#' data-bind='click: $root.compositions.removeComposition'>Delete comp</a></td>
</tr>
</tbody>
</table>
<a href='#' data-bind='click: $root.addComposition'>Add another composition</a>
</td>
</tr>
</tbody>
</table>
<a href='#' data-bind='click: $root.addFormulations'>Add formulations</a>
</td>
</tr>
</tbody>
</table>
</div>
<p>
<button data-bind='click: addBrandName'>Add a drug</button>
<button data-bind='click: save, enable: brandNames().length > 0'>Save to JSON</button>
</p>
<textarea data-bind='value: lastSavedJson' rows='5' cols='60' disabled='disabled'> </textarea>
</div>
Upvotes: 1
Views: 144
Reputation: 14531
It is clear that you need to formulation
object to remove the composition
. So in order to get the formulation
along with composition
, here's how I would write the click binding:
<a href='#' data-bind='click: function() {$root.removeComposition($data, $parent) }'>Delete comp</a>
Then, you could write the delete composition function as follows:
self.removeComposition = function(composition,formulation ) {
formulation.compositions.remove(composition);
};
$( document ).ready(function() {
var initialData = [
];
var brandNamesModel = function(brandNames) {
var self = this;
self.brandNames = ko.observableArray(ko.utils.arrayMap(brandNames, function(drug) {
return { brandName: drug.brandName, formulations: ko.observableArray(drug.formulations), compositions: ko.observableArray(drug.compositions) };
}));
self.addBrandName = function() {
self.brandNames.push({
brandName: "",
formulations: ko.observableArray(),
compositions: ko.observableArray()
});
};
self.removeBrandName = function(drug) {
self.brandNames.remove(drug);
};
self.addFormulations = function(drug) {
drug.formulations.push({
compositions: ko.observableArray()
});
};
self.removeFormulations = function(formulation) {
$.each(self.brandNames(), function() { this.formulations.remove(formulation) })
};
self.addComposition = function(drug) {
drug.compositions.push({
type: "",
number: ""
});
};
self.removeComposition = function(composition,formulation ) {
formulation.compositions.remove(composition);
};
self.save = function() {
self.lastSavedJson(JSON.stringify(ko.toJS(self.brandNames), null, 2));
};
self.lastSavedJson = ko.observable("")
};
ko.applyBindings(new brandNamesModel(initialData));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div class='container'>
<h2>brandNames</h2>
<div>
<table>
<tr>
<th>Brand name</th>
<th>formulations</th>
</tr>
<tbody data-bind="foreach: brandNames">
<tr>
<td>
<input data-bind='value: brandName' />
<div><a href='#' data-bind='click: $root.removeBrandName'>Delete brand name</a></div>
</td>
<td>
<table>
<tbody data-bind="foreach: formulations">
<tr>
<td><label>Formulation</label></td>
<td><select>
<option>Tablet</option>
<option>Syrap</option>
</select>
</td>
<td><a href='#' data-bind='click: $root.removeFormulations'>Delete</a></td>
<td>
<table>
<tbody data-bind="foreach: compositions">
<tr>
<td><input data-bind='value: type' /></td>
<td><input data-bind='value: number' /></td>
<td><a href='#' data-bind='click: function() {$root.removeComposition($data, $parent) }'>Delete comp</a></td>
</tr>
</tbody>
</table>
<a href='#' data-bind='click: $root.addComposition'>Add another composition</a>
</td>
</tr>
</tbody>
</table>
<a href='#' data-bind='click: $root.addFormulations'>Add formulations</a>
</td>
</tr>
</tbody>
</table>
</div>
<p>
<button data-bind='click: addBrandName'>Add a drug</button>
<button data-bind='click: save, enable: brandNames().length > 0'>Save to JSON</button>
</p>
<textarea data-bind='value: lastSavedJson' rows='5' cols='60' disabled='disabled'> </textarea>
</div>
Upvotes: 1