Binding dropdown values using knockout js - javascript

I have the below JS:
function RowData(Township, Range, Section,Crop, Acres) {
var self = this;
self.Township = Township;
self.Range = Range;
self.Section = Section;
self.Crop = [{ value: "1", crop: "Irrigated Corn" }, { value: "2", crop: "Irrigated Sugar Beets" }, { value: "3", crop: "Irrigated Soybeans" }, { value: "4", crop: "Irrigated Sorghum (Milo, Sudan)" }, { value: "5", crop: "Irrigated Dry Edible Beans" }, { value: "6", crop: "Irrigated Potatoes" }, { value: "7", crop: "Irrigated Alfalfa" }, { value: "8", crop: "Irrigated Small Grains" }, { value: "9", crop: "Range/Pasture/Grass (Brome, Hay, CRP)" }, { value: "10", crop: "Urban Land" }, { value: "11", crop: "Open Water" }, { value: "12", crop: "Riparian Forest and Woodlands" }, { value: "13", crop: "Wetlands" }, { value: "14", crop: "Other Agricultural Lands (Farmsteads, Feedlots, etc.)" }, { value: "15", crop: "Irrigated Sunflower" }, { value: "16", crop: "Summer Fallow" }, { value: "17", crop: "Roads" }, { value: "18", crop: "Dryland Corn" }, { value: "19", crop: "Dryland Soybeans" }, { value: "20", crop: "Dryland Sorghum" }, { value: "21", crop: "Dryland Dry Edible Beans" }, { value: "22", crop: "Dryland Alfalfa" }, { value: "23", crop: "Dryland Small Grains" }, { value: "24", crop: "Dryland Sunflower" }, { value: "25", crop: "Dryland Sugar Beets" }, { value: "26", crop: "Dryland Potatoes" }, { value: "27", crop: "Irrigated Hay" }, { value: "28", crop: "Irrigated Rotation Pasture" }];
self.Acres = Acres;
}
function PBHEPViewModel() {
var self = this;
//Present Conditions
self.present_conditions = ko.observableArray([
new RowData()
]);
self.present_AddRow = function () {
self.present_conditions.push(new RowData())
}
self.present_RemoveRow = function (row) { self.present_conditions.remove(row) };
//Future Conditions
self.future_conditions = ko.observableArray([
new RowData()
]);
self.future_AddRow = function () {
self.future_conditions.push(new RowData())
}
self.future_RemoveRow = function (row) { self.future_conditions.remove(row) };
//submit the data
self.submit_conditions = function () {
var PC_data = ko.toJSON(self.present_conditions());
var FC_data = ko.toJSON(self.future_conditions());
$.post("/Home/PBHEP", { "PC": PC_data, "FC": FC_data});
}
}
ko.applyBindings(new PBHEPViewModel());
And my HTML is:
<tbody data-bind="foreach:future_conditions">
<tr>
<td style =" text-align:center">
<input class="input-small" type="text" placeholder="Township" data-bind="value: Township"></td>
<td style =" text-align:center">
<input class="input-small" type="text" placeholder="Range"data-bind="value: Range"></td>
<td style =" text-align:center">
<input class="input-small" type="text" placeholder="Section"data-bind="value: Section"></td>
<td style =" text-align:center">
<select name="" data-bind="options: Crop, optionsValue: 'value', optionsText: function (i) { return i.crop }, optionsCaption: 'Choose a Crop...'"></select>
</td>
<td style =" text-align:center">
<input class="input-small" type="text" placeholder="Acres"data-bind="value: Acres"></td>
<td>
<button class="btn btn-small btn btn-danger" type="button" data-bind="click: $root.future_RemoveRow"><i class="icon-minus-sign icon-white"></i></button>
</td>
</tr>
</tbody>
When I do the post I have all the entire array in the crop field where i only want to post the value that has been selected.
How do I achieve this where am I going wrong.
Thank you in advance

For a single-select list, you use the value binding to write the selected value to your viewmodel. See the note near the top of the documentation for details.
Try the below binding:
<select name="" data-bind="options: Crop, value: Crop, optionsText: 'crop', optionsCaption: 'Choose a Crop...'"></select>
This displays the text in the drop down as the crop property of your array items. It also assigns the selected value from the drop down to the Crop property of the RowData object.
You may want to change the name of the array, Crop, to Crops or something to differentiate it from the singular property on the RowData object. It is a little confusing, as is.

Related

Show alert on input change in vue js

How can i display a confirmation alert only if i want to change radio button on previous step? So if i confirm my action all steps below should be removed.
I've binded a #change directive to the radio button with a method implementing the expected confirmation alert, but it appears on each change i make.
Here is my fiddle
Thanks for your advices in advance
new Vue({
el: "#app",
data() {
return {
answer: ["1"],
stepsData: [
{
id: "1",
yes_section: "2",
no_section: "4",
name: "Step 1",
},
{
id: "2",
yes_section: "5",
no_section: "1",
name: "Step 2",
},
{
id: "3",
yes_section: "2",
no_section: "4",
name: "Step 3",
},
{
id: "4",
yes_section: "2",
no_section: "4",
name: "Step 4",
},
{
id: "5",
yes_section: "2",
no_section: "4",
name: "Step 5",
},
],
};
},
computed: {
quation() {
return this.answer.map((answer) => {
return this.stepsData.find((step) => step.id === answer);
});
},
},
methods: {
pushAnswer(answer) {
this.answer.push(answer);
},
confirmPopup() {
alert('Are you sure?')
},
},
});
.step {
background: #ccc;
padding: 20px;
margin-bottom: 15px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div v-for="(step, id) in quation" :key="id" class="step">
<div v-html="step.name"></div>
<div>
<input
type="radio"
:id="step.UF_NO_SECTION"
:name="step.ID"
:value="step.yes_section"
#click="pushAnswer(step.yes_section)"
#change="confirmPopup"
/>
<label
:for="step.UF_NO_SECTION"
class="legal-aid__step-btn button _outline _no"
>
YES {{ step.yes_section }}
</label>
</div>
<div class="legal-aid__step-action_no">
<input
type="radio"
:id="step.UF_NO_SECTION"
:name="step.ID"
:value="step.no_section"
#click="pushAnswer(step.no_section)"
#change="confirmPopup"
/>
<label
:for="step.UF_NO_SECTION"
class="legal-aid__step-btn button _outline _no"
>
NO {{ step.no_section }}
</label>
</div>
</div>
</div>
I would add a property on every stepData that is called isSelected which will be initialized to false and once it was clicked, it will be changed to true.
So you data will look like this:
stepsData: [
{
id: "1",
yes_section: "2",
no_section: "4",
name: "Step 1",
isSelected: false
},
....
]
You will need to change pushAnswer to set isSelected to `true:
#click="pushAnswer(step)"
pushAnswer(answer) {
answer.isSelected = true;
this.answer.push(answer.yes_section);
},
And confirmPopup function will check if the answer is already selcted or not:
#change="confirmPopup(step)"
confirmPopup(step) {
if (step.isSelected) {
alert('Are you sure?')
}
},
Of course you can change anything to your liking, but this is the basic idea

how to select multiple options from a search input with Jquery typeahead.js plugin

I am using jQuery Typeahead plugin. I have a search input and dropdown list containing different values as you see below
for example if I select the shipment report, I will see just the shipment data as you see below
I want to use the multiselect options instead of selecting just one value. I am following the demo example Hockey v2 . I have enable the multiselect in my script but it's still selecting just one value.
Any suggestions please what am I missing in my code ? Thank you.
var data = [{
"name": "country",
"id": "country",
"typeReport": "shipment"
}, {
"name": "customer name",
"id": "customer name",
"typeReport": "shipment"
}, {
"name": "order number",
"id": "order number",
"typeReport": "serial"
}, {
"name": "line number",
"id": "line number",
"typeReport": "serial"
}];
typeof $.typeahead === 'function' && $.typeahead({
input: ".js-typeahead-input",
minLength: 0,
maxItem: 8,
maxItemPerGroup: 6,
order: "asc",
hint: true,
searchOnFocus: true,
group: {
key: "typeReport",
template: function (item) {
var typeReport = item.typeReport;
return typeReport; } },
emptyTemplate: 'no result for {{query}}',
groupOrder: ["shipment", "serial"],
display: ["name"],
correlativeTemplate: true,
dropdownFilter: [{
key: 'typeReport',
template: '<strong>{{typeReport}}</strong> typeReport',
all: 'All Reports'
}],
multiselect: {
minLength: 1 },
template: '<span>' +
'<span class="name">{{name}}</span>' +
'</span>',
source: {
groupName: {
data: data
}
},
debug: true
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/jquery-typeahead/2.7.0/jquery.typeahead.css" rel="stylesheet"/>
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/typeahead.js/0.11.1/typeahead.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-typeahead/2.7.0/jquery.typeahead.js"></script>
<form>
<div class="typeahead__container">
<div class="typeahead__field">
<span class="typeahead__query">
<input class="js-typeahead-input"
name="q"
type="search"
autofocus
autocomplete="on">
</span>
</div>
</div>
</form>
If you browse link as you mentioned "https://cdnjs.cloudflare.com/ajax/libs/jquery-typeahead/2.7.0/jquery.typeahead.js". There are no such type of attribute "multiselect".
It means that, you are using old version of type ahead script.
As per latest script "https://cdnjs.com/libraries/jquery-typeahead". Please see below are the example.
var data = [{
"name": "country",
"id": "country",
"typeReport": "shipment"
}, {
"name": "customer name",
"id": "customer name",
"typeReport": "shipment"
}, {
"name": "order number",
"id": "order number",
"typeReport": "serial"
}, {
"name": "line number",
"id": "line number",
"typeReport": "serial"
}];
typeof $.typeahead === 'function' && $.typeahead({
input: ".js-typeahead-input",
minLength: 0,
maxItem: 8,
maxItemPerGroup: 6,
order: "asc",
hint: true,
searchOnFocus: true,
group: {
key: "typeReport",
template: function(item) {
var typeReport = item.typeReport;
return typeReport;
}
},
emptyTemplate: 'no result for {{query}}',
groupOrder: ["shipment", "serial"],
display: ["name"],
correlativeTemplate: true,
dropdownFilter: [{
key: 'typeReport',
template: '<strong>{{typeReport}}</strong> typeReport',
all: 'All Reports'
}],
multiselect: {
limit: 5,
limitTemplate: 'You can\'t select more than 2 teams',
matchOn: ["id"],
data: function() {
var deferred = $.Deferred();
return deferred;
},
callback: {
onClick: function(node, item, event) {
event.preventDefault();
console.log(item);
alert(item.name + ' Clicked!');
},
onCancel: function(node, item, event) {
console.log(item)
}
}
},
template: '<span>' +
'<span class="name">{{name}}</span>' +
'</span>',
source: {
groupName: {
data: data
}
},
debug: true
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jquery-typeahead/2.10.6/jquery.typeahead.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-typeahead/2.10.6/jquery.typeahead.js"></script>
<div class="typeahead__container">
<div class="typeahead__field">
<span class="typeahead__query">
<input class="js-typeahead-input"
name="q"
type="search"
autofocus
autocomplete="on">
</span>
</div>
</div>

Angular filter with multiple dropdown

I am trying to filter with multiple dropdowns.
For example, when narrowing down by two numbers of value and num, there is no corresponding data when searching with "value = 1, num = 5", but data of "id = '000'" is displayed It will result.
Where should I fix it?
plunker:http://plnkr.co/edit/IBRDuHYtSCUFV1xNxjh4?p=preview
HTML
<body ng-controller="MainCtrl">
<div>
<div>
<div>
<span>value</span>
<select class="form-control" ng-model="value_1">
<option ng-repeat="value in product_value" value="{{value}}">{{value}}</option>
</select>
<span>num</span>
<select class="form-control" ng-model="num_1">
<option ng-repeat="num in product_num" value="{{num}}">{{num}}</option>
</select>
</div>
<div>
<span>value</span>
<select class="form-control" ng-model="value_2">
<option ng-repeat="value in product_value" value="{{value}}">{{value}}</option>
</select>
<span>num</span>
<select class="form-control" ng-model="num_2">
<option ng-repeat="num in product_num" value="{{num}}">{{num}}</option>
</select>
</div>
</div>
<table>
<tr>
<th>
id
</th>
<th>
name
</th>
</tr>
<tr ng-repeat="products in products | filter:{main:{value:value_1}} | filter:{main:{num:num_1}} |
filter:{main:{value:value_2}} | filter:{main:{num:num_2}}">
<td>{{products.id}}</td>
<td>{{products.name}}</td>
</tr>
</table>
</div>
JS
var app = angular.module('TestMode', []);
app.controller('MainCtrl', function($scope, $filter) {
$scope.product_value = ["1", "2", "3", "4", "5"];
$scope.product_num = ["1", "2", "3", "4", "5"];
$scope.products = [
{
id: "000",
name:'A',
main:[
{
value: "1",
num: "1"
},{
value: "1",
num: "2"
},{
value: "1",
num: "3"
},{
value: "2",
num: "4"
},{
value: "2",
num: "5"
}
]
},{
id: "001",
name:'B',
main:[
{
value: "5",
num: "5"
},{
value: "5",
num: "4"
},{
value: "5",
num: "3"
},{
value: "4",
num: "2"
},{
value: "4",
num: "1"
}
]
}
];
});
Use this below code instead of yours.
ng-repeat="products in products | filter:{main:{value:value_1,num:num_1}} |
filter:{main:{value:value_2,num:num_2}}"
Working demo : http://plnkr.co/edit/K5Xq3QOo1Kfs5Lw5yiAJ?p=preview
Change products to product.
Always filter by 2 properties instead of 1.
<tr ng-repeat="product in products | filter:{main:{value:value_1,num:num_1}} | filter:{main:{value:value_1,num:num_1}}">
<td>{{product.id}}</td>
<td>{{product.name}}</td>
</tr>
http://plnkr.co/edit/VXz8h5y8273rgHL7uMgS?p=preview

Doesn't works radio button angularjs

But I have problem when I checked radio button doesn't change ng-model="title"
I changed this code a lot but I can not find a solution. Can someone help, I think there is a problem here in ng-repeat?
Can someone help solve this problem?
I have code:
<div class="container">
<label data-ng-repeat="option in dbQuestion">
<input type="radio" name="form-field" ng-model="title" value="{{option.title}}" ng-checked="$index == 0" />
{{option.title}}
</label>
<span>{{title}}</span>
</div>
__
var app = angular.module("SampleApp", []);
app.controller("SampleAppCtrl", function($scope) {
$scope.dbQuestion = [{
title: "Question 1",
descripton: "Description 1",
answers: [{
item1: "item1",
value: true
},
{ item2: "item2", value: true },
{ item3: "item3", value: true },
{
item4: "item4",
value: true
}
]
},
{
title: "Question 5",
descripton: "Description 5",
answers: [{
item1: "item1",
value: true
},
{ item2: "item2", value: true },
{ item3: "item3", value: true },
{
item4: "item4",
value: true
}
]
},
];
$scope.title = $scope.dbQuestion[0].title;
});
New AngularJS developers often do not realize that ng-repeat, ng-switch, ng-view, ng-include and ng-if all create new child scopes, so the problem often shows up when these directives are involved. (See this example for a quick illustration of the problem.)
This issue with primitives can be easily avoided by following the "best practice" of always have a '.' in your ng-models – watch 3 minutes worth. Misko demonstrates the primitive binding issue with ng-switch.
Having a '.' in your models will ensure that prototypal inheritance is in play. So, use
<label data-ng-repeat="option in dbQuestion">
<input type="radio" name="form-field"
ng-model="title.selected"
value="{{option.title}}"
ng-checked="$index == 0" />
{{option.title}}<br>
</label>
<p>Selected - {{title.selected}}</p>
app.controller("ctrl", function($scope) {
$scope.title = { selected: ''};
$scope.dbQuestion = [{ /*..*/ }];
});
For more information, see AngularJS Wiki - The Nuances of Scope Prototypal Inheritance.
The DEMO
angular.module("app", [])
.controller("ctrl", function($scope) {
$scope.title = { selected: ''};
$scope.dbQuestion = [{
title: "Question 1",
descripton: "Description 1",
answers: [{
item1: "item1",
value: true
},
{ item2: "item2", value: true },
{ item3: "item3", value: true },
{
item4: "item4",
value: true
}
]
},
{
title: "Question 5",
descripton: "Description 5",
answers: [{
item1: "item1",
value: true
},
{ item2: "item2", value: true },
{ item3: "item3", value: true },
{
item4: "item4",
value: true
}
]
},
];
});
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="app" ng-controller="ctrl">
<div class="container">
<label data-ng-repeat="option in dbQuestion">
<input type="radio" name="form-field"
ng-model="title.selected"
value="{{option.title}}"
ng-checked="$index == 0" />
{{option.title}}<br>
</label>
<p>Selected - {{title.selected}}</p>
</div>
</body>
You need to use $parent.title instead of title, like this :
<input type="radio" name="form-field" ng-model="$parent.title" value="{{option.title}}" ng-checked="$index == 0" />
ng-repeat creates its own scope and in order to assign the value to the parent scope from the child scope we need to use $parent

Populate dependent dropdown from arrays only using AJAX Jquery

I'm trying to do a form with dropdown dependable options, the problem is that I can just use HTML, Javascript and Ajax, no database, so I have to fill the options directly with jquery, so far this is what I got, but is not working, any help would awesome, thank you :)
$(document).ready(function(){
var countries = [
{
"id": "1",
"name": "Mexico"
},
{
"id": "2",
"name": "USA"
},
{
"id": "3",
"name": "Canada"
}
]
var states = {
'mexico': [{
display: "Ciudad de Mexico",
value: "mx-city"
}, {
display: "Jalisco",
value: "jalisco"
}],
'usa': [{
display: "Texas",
value: "texas"
}, {
display: "Ohio",
value: "ohio"
}],
'canada': [{
display: "Montreal",
value: "montreal"
}, {
display: "Toronto",
value: "toronto"
}]
};
var states = {
'mx-city': [{
display: "Benito Juarez",
value: "benito-juarez"
}, {
display: "Cuauhtemoc",
value: "cuauhtemoc"
}],
'jalisco': [{
display: "Zapopan",
value: "zapopan"
}, {
display: "Guadalajara",
value: "Guadalajara"
}],
'texas': [{
display: "San Antonio",
value: "san-antonio"
}, {
display: "Austin",
value: "austin"
}],
'ohio': [{
display: "Colombus",
value: "colombus"
}, {
display: "Cleveland",
value: "cleveland"
}],
'montreal': [{
display: "Quebec",
value: "Quebec"
}, {
display: "Vermont",
value: "vermont"
}],
'toronto': [{
display: "Ontario",
value: "ontario"
}, {
display: "York",
value: "york"
}]
};
$("#country").on('click',function() {
var pais = $(this).val();
$("#country").find("option").remove();
$(countries).each(function (i) {
$("#country").append('<option id="'+countries[i].id+'">'+countries[i].name+"</option>");
});
console.log(pais);
});
function list(array_list){
$("#child_selection").html("");
$(array_list).each(function (i) {
$("#child_selection").append('<option value="'+array_list[i].value+'">'+array_list[i].display+"</option>");
});
}
$('#child_selection').change(function() {
var state = $(this).val();
if (states[state] == undefined) {
return $("#child").text('Selecciona tu ciudad');
}
list(states[state]);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script><form action="" method="" enctype="application/json">
<br/>Nombre: <input type="text" />
<br/>Edad: <input type="text" />
<br/>Pais:
<select name="country" id="country">
<option value="">Selecciona tu pais</option>
</select>
<br />Estado:
<select name="child_selection" id="child_selection">
<option value="">Selecciona tu estado</option>
</select>
<br/>Ciudad:
<select name="child" id="child">
<option value="">Selecciona tu ciudad</option>
</select>
<input type="submit" value="Submit" />
</form>
First of all you have 2 variables with the same name states and your code is not according to the format of your JSON. Below the code i have fixed. Have a look.
$(document).ready(function() {
var countries = [{
"id": "1",
"name": "Mexico"
}, {
"id": "2",
"name": "USA"
}, {
"id": "3",
"name": "Canada"
}]
var states = {
'mexico': [{
display: "Ciudad de Mexico",
value: "mx-city"
}, {
display: "Jalisco",
value: "jalisco"
}],
'usa': [{
display: "Texas",
value: "texas"
}, {
display: "Ohio",
value: "ohio"
}],
'canada': [{
display: "Montreal",
value: "montreal"
}, {
display: "Toronto",
value: "toronto"
}]
};
var cities = {
'mx-city': [{
display: "Benito Juarez",
value: "benito-juarez"
}, {
display: "Cuauhtemoc",
value: "cuauhtemoc"
}],
'jalisco': [{
display: "Zapopan",
value: "zapopan"
}, {
display: "Guadalajara",
value: "Guadalajara"
}],
'texas': [{
display: "San Antonio",
value: "san-antonio"
}, {
display: "Austin",
value: "austin"
}],
'ohio': [{
display: "Colombus",
value: "colombus"
}, {
display: "Cleveland",
value: "cleveland"
}],
'montreal': [{
display: "Quebec",
value: "Quebec"
}, {
display: "Vermont",
value: "vermont"
}],
'toronto': [{
display: "Ontario",
value: "ontario"
}, {
display: "York",
value: "york"
}]
};
$(countries).each(function(i) {
$("#country").append('<option id="' + countries[i].id + '">' + countries[i].name + "</option>");
});
$("#country").on('change', function() {
list(states[$("#country").val().toLowerCase()]);
});
function list(array_list) {
$("#child_selection").html("");
$(array_list).each(function(i) {
$("#child_selection").append('<option value="' + array_list[i].value + '">' + array_list[i].display + "</option>");
});
}
$('#child_selection').change(function() {
var state = $(this).val();
if (cities[state] == undefined) {
return $("#child").text('Selecciona tu ciudad');
}
array_list = cities[state.toLowerCase()];
$("#child").html("");
$(cities[state]).each(function(i) {
$("#child").append('<option value="' + array_list[i].value + '">' + array_list[i].display + "</option>");
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<br/>Nombre:
<input type="text" />
<br/>Edad:
<input type="text" />
<br/>Pais:
<select name="country" id="country">
<option value="">Selecciona tu pais</option>
</select>
<br />Estado:
<select name="child_selection" id="child_selection">
<option value="">Selecciona tu estado</option>
</select>
<br/>Ciudad:
<select name="child" id="child">
<option value="">Selecciona tu ciudad</option>
</select>
<input type="submit" value="Submit" />
</form>
Hope it helps :)

Categories