Set and modify a value in a select box with knockout - javascript

Well, I have two problems that worry me a lot ... First, I don't know how to give a default value to the select box.
And I I'm not able to change the value of the select box via an event click ... I've created a fiddle example if someone could give me a hand it would be very appreciated!
HTML
<select id="FilterBox" data-bind="value: siteGetOne">
<option value="-2">City Wide</option>
<!-- ko foreach: sites -->
<option data-bind="text: name, value: $data"></option>
<!-- /ko -->
</select>
Selection Option Object : <span data-bind="text: siteGetOne"></span><br/>
Selection Option name : <span data-bind="text: siteGetOne().name"></span><br/>
Selection Option id : <span data-bind="text: siteGetOne().id"></span><br/>
Set Value to 1
Set Value to 2
Set Value to 3
JS
var viewModel = function() {
var self = this;
setValue = ko.observable();
self.sites = [
{ name: 'Site 1', id: 1},
{ name: 'Site 2', id: 2},
{ name: 'Site 3', id: 3}
];
self.siteGetOne = ko.observable(self.sites[2].id);
self.siteGetOne.subscribe(function (newValue) {
console.log(newValue);
}, self);
}
ko.applyBindings(new viewModel());
http://jsfiddle.net/xjYcu/276/
Edited Final version : http://jsfiddle.net/xjYcu/286/

couple things you may want to change.
here is the entire fiddle. http://jsfiddle.net/xjYcu/283/
the first one is you should use the options binding for your select.
<select id="FilterBox" data-bind=" options: sites,
optionsText: 'name',
value: siteGetOne,
optionsCaption: 'Choose...'">
</select>
also try changing your click bindings to something like this so you can pass in your parameter.
Set Value to 1
Set Value to 2
Set Value to 3

Related

Show value instead of text in Knockout-bound dropdown

I'm having an HTML dropdown, where I use Knockout.js to bind the options. With the dropdown, you can select ISO country codes. In the (short) dropdown, I want to display the two-letter country code as text. The full names of the countries should only appear, when the user opens the dropdown. Something like:
+=======+===+
| DE | v |
+=======+===+
| Germany |
| England |
| France |
| Spain |
| USA |
+-----------+
Right now, my HTML code looks like this:
<select class="form-control w-25" data-bind="
value: customAddress.country,
options: countryList,
optionsText: 'name',
optionsValue: 'code',
optionsCaption: 'Country'
" required></select>
Obviously, the dropdown displays "Germany" right now, if you select it. I found some ideas to replace the display text of the dropdown using jQuery in the onBlur event. But I fear, that this will interfere with the data binding mechanism of knockout (all properties are observables).
How can I solve that? Do I need a custom binding?
You don't necessarily need a custom binding handler (and certainly don't need to resort to jQuery); this could be accomplished using the default binding handlers.
Store the select menu state (open/closed) in a variable;
Toggle this variable on the blur/focus events using the event binding. If it's a focus event, we assume the menu is open; if it's a blur event, we assume menu is closed.
Pass a function to optionsText that will return either the code or the country, depending on the value of said variable.
JS:
function ViewModel() {
var vm = this;
vm.countries = [{
code: 'DE',
country: 'Germany'
},
{
code: 'NL',
country: 'The Netherlands'
},
{
code: 'BE',
country: 'Belgium'
}
];
vm.countrySelectIsOpen = ko.observable(false);
vm.selectedCountry = ko.observable();
vm.getOptionsText = function(item) {
return item[vm.countrySelectIsOpen() ? 'country' : 'code'];
}
vm.toggleCountrySelectStatus = function(data, event) {
vm.countrySelectIsOpen(event.type === 'focus');
}
}
ko.applyBindings(new ViewModel)
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<select class="form-control" data-bind="
options: countries,
optionsText: getOptionsText,
optionsValue: 'code',
optionsCaption: 'Country',
value: selectedCountry,
event: {
blur: toggleCountrySelectStatus,
focus: toggleCountrySelectStatus
}
"></select>
Fiddle: https://jsfiddle.net/thebluenile/hf70kg84/

AngularJS Select | After selecting an id from a JSON show the rest of the information of that id

I have a JSON saved that has plenty information:
I am able to fill a select menu with all the names of each element inside the JSON this way:
<select ng-model="car.marca" ng-options="item.brakeId as item.name for item in fillBreaks" class="form-control cforms" required>
<option value="" disabled selected>Sleccionar Marca</option>
</select>
Getting this as result: a select menu filled with the names:
I am able to get the BreakId of the selected element, in this case is saved in 'car.marca' using ng-model.
ng-model="car.marca"
My question is, Based on the selected element lets say 'BrakeId: 9' how can I display the rest of the information of that selected id?
I want to display the price, description, stock, and so on.
You can get the selected object by doing a find on fillBreaks (should be fillBrakes?) for an object with a matching brakeId using ng-change like below. This will allow you to display the additional brake information while keeping car.marca true to holding just a brakeID.
var exampleApp = angular.module('exampleApp', []);
exampleApp.controller('ExampleController', ['$scope', function($scope) {
$scope.car = null;
$scope.fillBreaks = [
{ brakeId: 0, name: 'Brake A', description: 'Good brakes', price: 100, stock: 1 },
{ brakeId: 1, name: 'Brake B', description: 'Great brakes', price: 200, stock: 1 },
{ brakeId: 2, name: 'Brake C', description: 'The best brakes', price: 300, stock: 1 }
];
$scope.brakeInfo = null;
$scope.getBrakeInfo = function(brakeId) {
$scope.brakeInfo = $scope.fillBreaks.find(function(item){return item.brakeId == brakeId});
}
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="exampleApp" ng-controller="ExampleController">
<select ng-model="car.marca" ng-options="item.brakeId as item.name for item in fillBreaks" ng-change="getBrakeInfo(car.marca)" class="form-control cforms" required>
<option value="" disabled selected>Sleccionar Marca</option>
</select>
<p>{{ brakeInfo }}</p>
</div>
You can change your ng-options to grab the entire selected object, instead of just it's ID.
ng-options="item as item.name for item in ctrl.fillBreaks"
See this JSFiddle for example
P.S. A little trick to remove the Placeholder option from the dropdown is to add style="display: none;" to it, so that it can't be intentionally selected; also illustrated in the JSfiddle

Select box placeholder in HTML Template

Code in controller:
$scope.infoOptions = [
{ name: 'Select Option', value: '0' },
{ name: 'Some Option', value: '1' }
];
HTML:
<select data-ng-model="nothing" data-ng-options="info.name for info in infoOptions ">
</select>
Angular puts that damn empty option at the top/selected by default. I've seen some answers to this question that suggest selecting a default option in the $scope for the form, but this select box is in a template in a dynamic form (ie. can be a number of select boxes). This is really only for demonstration purposes - is there anyway I can get rid of that empty option in a template?

Angularjs show selected option from ng-repeat value

I have drop down inside ng-repeat as follows.
<div ng-model="list in lists">
<div>
<select ng-model="pType" ng-options="c.name in projType"></select>
<option value="{{list.value}"></option>
</div>
My Controller is
App.controller('pOverCtrl', function ($scope, pOverRepository, $location) {
$scope.lists = projOverRepository.query();
$scope.projType = [
{ value: '0', name: 'None Selected' },
{ value: '1', name: 'Construction' },
{ value: '2', name: 'Maintenance' },
];
})
The dropdown gets populated fine. But my goal is that when ng-repeat is executed it automatically shows the value that is coming from lists scope as selected.
Please let me know how to fix this issue.
use the diretive ng-selected
<div ng-model="list in lists">
<select ng-model="pType" ng-options="c.name in projType">
<option ng-selected="list.value == list.selected" value="{{list.value}"></option>
</select>
</div>
assuming that list.selected variable contains the value of the option selects
$scope.pType should have the selected value as it's bind by ng-model.
Read the docs here: http://docs.angularjs.org/api/ng/directive/select
And if you already have the selected value in $scope.lists, you can use the ngSelected directive.

Using drop down selection to populate a text box with a default in KnockoutJS

I have a fairly simple order creation form on a back office app I'm building. The scenario I cannot figure out is under the "Order lines" section of the form. I want it so that you click add row the row appears which contains a drop down containing all the products, then 2 text boxes for quantity and price. I want it so that when a product is selected, that products price is set as the default value in the Price text box, but the use is able to change it still.
So far I have everything in- you can add rows, you can select the part- the only piece i cannot figure out how to do correctly is to populate the default price. So a cut down version of my knockout viewModel looks like this;
viewModel = {
Parts : ko.observableArray(initialData.Parts),
Sale : ko.observable(initialData.Sale),
SaleLines : ko.observableArray(initialData.SaleLines),
addRow: function() {
this.SaleLines.push({ Id: "00000000-0000-0000-0000-000000000000", SalePrice : 0.00, Qty : 1, PartId: "" });
$("select").combobox({
selected: function (event, ui) {
$(ui.item.parentNode).change();
}
});
},
removeRow: function (r) {
this.SaleLines.remove(r);
}
}
The Sale lines are rendered out through a template like this;
<script type="text/html" id="saleLineTemplate">
<tr>
<td>
<select data-bind='options: viewModel.Parts, optionsText: "Description", optionsCaption: "Select...", optionsValue: "Id", value: PartId, uniqueName: true' class="mustPopulateDropdown"></select>
</td>
<td>
<input data-bind="value: Qty, uniqueName: true" class="required number"/>
</td>
<td>
<input data-bind="value: SalePrice, uniqueName: true" class="required number"/>
</td>
<td>
Delete
</td>
</tr>
</script>
The actual Parts collection comes from the backend MVC, and is passed as a List with PartDTO just having Id, Description and Price.
I just cannot think of the correct way to do this- i figured I maybe make the Id field of each SaleLine observable when I create it then somehow make it update the SalePrice on update, but just can't think how to implement it?
Thanks in advance for your help!
How about something like this: http://jsfiddle.net/rniemeyer/VLVuC/
Basically, make it so the "value" of the dropdown is a "SelectedPart" observable that is set to the corresponding Part object:
<select data-bind='options: viewModel.Parts, optionsText: "Description", optionsCaption: "Select...", value: SelectedPart, uniqueName: true' class="mustPopulateDropdown"></select>
Then, subscribe to the SelectedPart changing and set your SalePrice based on SelectedPart().Price.
addRow: function() {
var newRow = {
Id: "00000000-0000-0000-0000-000000000000",
Qty: ko.observable(1),
SalePrice: ko.observable(0),
SelectedPart: ko.observable()
};
newRow.SelectedPart.subscribe(function() {
this.SalePrice(this.SelectedPart() ? this.SelectedPart().Price : 0);
}, newRow);
Whenever, the dropdown changes on a row, then the SalePrice will be defaulted to the new selected product's price (unless they pick the "Select..." line).
Hope this helps.

Categories