So far, my code binds data to choices object, and then add field input dynamically when clicking "add course" button. Then, uses $http.get to return json data from the server and binds it to select option. Although when I choose an option, it only selects applied option.
HTML:
<div ng-app="timeTable" ng-controller="addCoursesCtrl">
<button ng-click="addNewCourse()">Add New Course</button>
<fieldset ng-repeat="choice in choices">
<select ng-model="choice.type"
ng-options="s.value as s.name for s in coursetoAdd">
<option value="{{s.value}}">{{s.value}}</option>
</select>
<input ng-model="choice.course">
</fieldset>
<button ng-click="convertAndSend()">Submit</button>
</div>
Javascript:
var timeTable = angular.module("timeTable",[]);
timeTable.controller("addCoursesCtrl", function ($scope,$http) {
$scope.choices = [{ course: '', type: '' }];
$scope.coursetoAdd = $scope.choices;
$http.get("/Semster/getSuggtedCourses").then(function (response) {
$scope.coursetoAdd = response.data;
});
$scope.addNewCourse = function () {
var newITemNo = $scope.choices.length + 1;
$scope.choices.push({ course: '', type: '' });
};
$scope.convertAndSend = function () {
var asJson = angular.toJson($scope.choices);
console.log(asJson);
$http.post('/Semster/Add', asJson);
};
});
Related
So I have this code
$(document.body).on('click', '.btn-create-tournament', function () {
var title = $(".create-tournament-title").val();
var format = $(".create-tournament-format").val();
var sport = $(".create-tournament-sport").val();
var prize = $(".create-tournament-prize").val();
var date = $(".create-tournament-date").val();
var location = $(".create-tournament-location").val();
var teams = $(".create-tournament-teams").val();
$.post('/Tournament/Create', {
title: title,
format: format,
sport: sport,
prize: prize,
date: date,
location: location,
teams: teams
}, function (response) {
if (response > 0) {
window.location.href = "/Tournament/Details/" + response;
}
})
}).on('input', '.search-teams', function () {
var query = this.value;
$.get('/Teams/Search', { name: query }, function (response) {
$('.search-team-results').html($(response).find('.team-results-search').html());
})
})
and then I call the input function here
#model List<TeamViewModel>
<div class="search-team-results">
#foreach (var item in Model)
{
<div>
<label class="team-results-search" data-team-id="#item.Id">#item.Name</label>
</div>
}
</div>
and finally it goes there
<h6>Players</h6>
<div class="form-outline">
<input class="search-teams" type="search" placeholder="Type query" aria-label="Search" />
<div class="search-team-results">
</div>
</div>
so I'm searching in a input field for the teams but they are showing below the field as label only and my question is how to make a script to actually add them to my list which is in my viewmodel?
$(response).find('.team-results-search').html()
will only get you the inner html (only text in this case) of the first label in the result list. To get the whole list use
$(response).find('.search-team-results').html()
I have to select drop down list value dynamically for update functionality in my web site. I also go through similar tutorials and stack overflow question-answer.
I work with angularjs v1.4.2, up till now I tried below code.
HTML:
<label for="ddlDesignationDepartment"> Department</label>
<select name="ddlDesignationDepartment" ng-model="designation.DepartmentId"
ng-options="dept.DepartmentId as dept.DepartmentName for dept in departmentList track by dept.DepartmentId" >
</select>
<br/>
<label for="txtDesignationName"> Designation</label>
<input type="text" name="txtDesignationName"
ng-model="designation.DesignationName"
placeholder="Designation name"/>
<br/>
<label for="txtDescription"> Description</label>
<input type="text" name="txtDescription"
ng-model="designation.Description"
placeholder="Desription"/>
<input type="button" value="{{designation.DesignationId>0?'Update':'Insert'}}"
ng-click="ManageDesignation(designation)" />
<table name="tblDesignationResult">
<tbody ng-if="designationList.length>0">
<tr ng-repeat="des in designationList">
<td>
{{$index+1}}
</td>
<td >
{{des.DesignationName}}
</td>
<td>
{{des.Description}}
</td>
<td >
{{des.DepartmentName}}
</td>
<td>
<input type="button" value="Edit" ng-click="EditDesgnation(des)" />
</td>
</tr>
</tbody>
</table>
AngularJs code:
(function () {
'use strict';
///Decalre angular controllar for Designation
angular.module('AngularDemo').controller('DesignationCtrl', ['$scope', '$rootScope', 'DesignationService', 'DepartmentService', DesignationCtrl]);
///Designation controllar
function DesignationCtrl($scope, $rootScope, DesignationService,
DepartmentService) {
///Get or set all Designation
$scope.designationList = [];
///Get or set all Department
$scope.departmentList = [];
///Get or set Designation
$scope.designation = new Designation();
///Retrive all Designation by DesignationService
$scope.GetAllDesignations = function () {
DesignationService.GetAllDesignations().then(function (response) {
if (response && response.data) {
/// Success block
if (response.data.Result) {
$scope.designationList = angular.copy(response.data.Result);
}
else {
alert(response.data.Message);
}
}
});
}
/// Manage Insert / Update / Delete on specific Designation by
///DesignationService
$scope.ManageDesignation = function ( des) {
DesignationService.ManageDesignation(des).then(function (response) {
if (response && response.data) {
/// Success block
if (response.data.Result) {
$scope.departmentList = angular.copy(response.data.Result);
}
else {
alert(response.data.Message);
}
}
});
$scope.Init();
}
///Retrive all Department by DepartmentService
$scope.GetAllDepartments = function () {
DepartmentService.GetAllDepartments().then(function (response) {
if (response && response.data) {
/// Success block
if (response.data.Result) {
$scope.departmentList = angular.copy(response.data.Result);
}
else {
alert(response.data.Message);
}
}
});
}
///Edit Designation
$scope.EditDesgnation = function (des) {
$scope.designation = des;
}
///Inilise Designation controllar
$scope.Init = function () {
$scope.designation = new Designation();
$scope.GetAllDesignations();
$scope.GetAllDepartments();
}
}
})();
///JavaScript Class of Designation
function Designation() {
this.DesignationId = 0;
this.DesignationName='';
this.Description = '';
this.DepartmentId = 0;
}
Designation.prototype = {
constructor: Designation
}
Sample Database
Department{DepartmentId int, DepartmentName varchar(max)}
Designation{DesignationId int,DesignationName varchar(max),Description varchar(max),DepartmentId int}
All services working fine, initially everything is fine all data are display in Result table, Dropdown list was also show all departments. But the problem is when I click on edit for update any record textbox value are filled for specific data but the Department Dropdown list value are not select.
Be careful when using select as and track by in the same expression.
Given this array of items on the $scope:
$scope.items = [{
id: 1,
label: 'aLabel',
subItem: { name: 'aSubItem' }
}, {
id: 2,
label: 'bLabel',
subItem: { name: 'bSubItem' }
}];
This will work:
<select ng-options="item as item.label for item in items track by item.id" ng-model="selected"></select>
$scope.selected = $scope.items[0];
but this will not work:
<select ng-options="item.subItem as item.label for item in items track by item.id" ng-model="selected"></select>
$scope.selected = $scope.items[0].subItem;
In both examples, the track by expression is applied successfully to each item in the items array. Because the selected option has been set programmatically in the controller, the track by expression is also applied to the ngModel value. In the first example, the ngModel value is items[0] and the track by expression evaluates to items[0].id with no issue. In the second example, the ngModel value is items[0].subItem and the track by expression evaluates to items[0].subItem.id (which is undefined). As a result, the model value is not matched against any and the appears as having no selected value
so in your case as well change this
ng-options="dept.DepartmentId as dept.DepartmentName for dept in departmentList track by dept.DepartmentId
to
ng-options="dept as dept.DepartmentName for dept in departmentList track by dept.DepartmentId
since dept[0].DepartmentId.id do not exists
In the following code, a product (represented with productVM) has an observable property (productName) containing its name in two languages (english and french).
Once a cartItem is added, and a product is selected, I want its displayed name to be updated when the button "change language" is clicked (e.g., if "Door" is selected, and "change language" is then clicked, the displayed name should be the french version (which is simply the english word plus a french-ish suffix "eux")).
But it doesn't work: The options do change, but the selected option is changed to the caption option.
What needs to be changed/added to fix it?
var handlerVM = function () {
var self = this;
self.cartItems = ko.observableArray([]);
self.availableProducts = ko.observableArray([]);
self.language = ko.observable();
self.init = function () {
self.initProducts();
self.language("english");
}
self.initProducts = function () {
self.availableProducts.push(
new productVM("Shelf", ['White', 'Brown']),
new productVM("Door", ['Green', 'Blue', 'Pink']),
new productVM("Window", ['Red', 'Orange'])
);
}
self.getProducts = function () {
return self.availableProducts;
}
self.getProductName = function (product) {
if (product != undefined) {
return self.language() == "english" ?
product.productName().english : product.productName().french;
}
}
self.getProductColours = function (selectedProductName) {
selectedProductName = selectedProductName();
// if not caption
if (selectedProductName) {
var matched = ko.utils.arrayFirst(self.availableProducts(), function (product) {
return (self.language() == "english" ? product.productName().english : product.productName().french) == selectedProductName;
});
return matched.availableColours;
}
}
self.addCartItem = function (a, b, c, d) {
self.cartItems.push(new cartItemVM());
}
self.changeLanguage = function () {
self.language() == "english" ?
self.language("french") :
self.language("english");
}
}
self.productVM = function (name, availableColours) {
var self = this;
self.productName = ko.observable({
english: name,
french: name + "eux",
});
self.availableColours = ko.observableArray(availableColours);
}
self.cartItemVM = function () {
var self = this;
self.cartItemName = ko.observable();
self.cartItemColour = ko.observable();
}
var handler = new handlerVM();
handler.init();
ko.applyBindings(handler);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div>
<div data-bind="foreach: cartItems">
<div>
<select data-bind="options: $parent.getProducts(),
optionsText: function (item) { return $parent.getProductName(item); },
optionsValue: function (item) { return $parent.getProductName(item); },
optionsCaption: 'Choose a product',
value: cartItemName"
>
</select>
</div>
<div>
<select data-bind="options: $parent.getProductColours(cartItemName),
optionsText: $data,
optionsCaption: 'Choose a colour',
value: cartItemColour,
visible: cartItemName() != undefined"
>
</select>
</div>
</div>
<div>
<button data-bind="text: 'add cart item', click: addCartItem" />
<button data-bind="text: 'change language', click: changeLanguage" />
</div>
</div>
Your problem occurs when you change the options of your select. During the change, your value bound observable, cartItemName, contains the English string. For example: Door. As soon as you change the language, there is not a single option that returns Door for its optionsValue expression, thereby clearing the value altogether.
The best solution is to store a reference to your actual viewmodel, rather than just its string name. This does require you to move some other bits & pieces around, since you're manually updating quite a bit.
The starting point of the change:
// Remove
self.cartItemName = ko.observable();
// Add
self.cartItem = ko.observable();
// Change
<select data-bind="...
value: cartItem
" />
In a working snippet, with some other changes to make my work easier:
var handlerVM = function () {
var self = this;
self.cartItems = ko.observableArray([]);
self.language = ko.observable("english");
self.availableProducts = ko.observableArray([
new productVM("Shelf", ['White', 'Brown']),
new productVM("Door", ['Green', 'Blue', 'Pink']),
new productVM("Window", ['Red', 'Orange'])
]);
self.productNameFor = function(product) {
return product.productName()[self.language()];
};
self.addCartItem = function (a, b, c, d) {
self.cartItems.push(new cartItemVM());
}
self.changeLanguage = function () {
self.language() == "english" ?
self.language("french") :
self.language("english");
}
}
self.productVM = function (name, availableColours) {
var self = this;
self.productName = ko.observable({
english: name,
french: name + "eux",
});
self.availableColours = ko.observableArray(availableColours);
}
self.cartItemVM = function () {
var self = this;
self.cartItem = ko.observable();
self.cartItemColour = ko.observable();
}
ko.applyBindings(new handlerVM());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div>
<div data-bind="foreach: cartItems">
<div>
<select data-bind="options: $root.availableProducts,
optionsText: $root.productNameFor,
optionsCaption: 'Choose a product',
value: cartItem"
>
</select>
</div>
<div data-bind="with: cartItem">
<select data-bind="options: availableColours,
optionsCaption: 'Choose a colour',
value: $parent.cartItemColour"
>
</select>
</div>
</div>
<div>
<button data-bind="text: 'add cart item', click: addCartItem" />
<button data-bind="text: 'change language', click: changeLanguage" />
</div>
</div>
I have two connected dropdowns that I'm using with Knockout. Both of them I'm populating with a simple Value,Text pair that I load from an ajax call.
When I go to change the value however I always get the previous value from the selected list. So if the default RegionCode value is "-1" the first RegionCode value that will be passed to the loadLocationList when I change it to another region will be "-1" even if the actual selected value is different that what I get by inspecting the element or through JQuery
Model
define([
'util',
'locationService',
'jquery',
'knockout',
'knockoutmapping',
function(util, svc, $, ko, mapped) {
var LocationViewModel = function(regionCodes, regionCode, locationCodes, locationCode, currentYear) {
var self = this;
self.CurrentYear = currentYear;
self.RegionCode = ko.observable(regionCode)
self.RegionCodes = ko.observableArray(regionCodes)
self.LocationCode = ko.observable(locationCode)
self.LocationCodes = ko.observableArray(locationCodes)
self.loadLocationList = function() {
self.LocationCodes([]);
var locationListCallback = function(data){
for (var i = 0; i < data.length; i++) {
self.LocationCodes.push(new SelectListPair(data[i].Value, data[i].Text));
}
}
svc.getLocationsInRegion(self.CurrentYear, self.RegionCode, true, locationListCallback);
}
}
var SelectListPair = function (value, text) {
this.Value = ko.observable(value);
this.Text = ko.observable(text);
}
return function summaryViewModel() {
var self = this;
self.LocationSummaryViewModel = ko.observable();
var initViewModel = function() {
$.ajax({
url: 'Url here',
success: function(vm) {
var locationVM = vm.LocationSummaryViewModel;
var selectListArray = locationVM.LocationList;
var selectList = [];
for (var i = 0; i < selectListArray.length; i++) {
var SelectListPair = {
Value: ko.observable(selectListArray[i].Value),
Text: ko.observable(selectListArray[i].Text),
};
selectList.push(SelectListPair);
}
var location = [new SelectListPair("-1", "Please select a location")];
self.LocationSummaryViewModel(new LocationViewModel(vm.CurrentYear, selectList, "-1", location, "-1"));
},
});
}
}
self.initViewModel();
});
View
<!-- ko with: LocationSummaryViewModel() -->
<div class="panel panel-default" data-bind="visible: Visible()">
<div class="panel-heading">
<div class="row">
<div class="col-md-4">
Location Summary
</div>
<div class="col-md-4">
<select class="form-control" data-bind="
options: RegionCodes(),
disable: RegionCodes().length === 1,
optionsText: 'Text',
optionsValue: 'Value',
event: {change: loadLocationList },
value: RegionCode">
</select>
</div>
<div class="col-md-4">
<select class="form-control" data-bind="
options: LocationCodes(),
disable: LocationCodes().length === 1,
optionsText: 'Text',
optionsValue: 'Value',
value: LocationCode">
</select>
</div>
</div>
</div>
<div class="panel-body">
Neat content
</div>
<div class="panel-footer">
</div>
</div>
<!-- /ko -->
Don't bind to the change event on a select. Subscribe to the value variable instead. In Knockout, the idea is always to represent the view in the model, and then use the view exclusively.
Suppose I want to add 'Add More' button next to input type file field.
So that on click of 'Add More' button one more file field will be created.
I could use '.clone()' for this in JQuery.
But how will I do this in AngularJS?
Thanks!!
In controller:
$scope.addMore = function() {
$scope.inputs += 1;
};
$scope.range = function(count) {
var inputs = [];
for (var i = 0; i < count; i++) {
inputs.push(i)
}
return inputs;
}
$scope.inputs = 0;
In HTML:
<input ng-repeat="n in range(inputs)">
<button ng-click="addMore()">Add more!</button>
MORE USEFUL VERSION:
Typically you want to have other information related to the input field though, so depending on your use case, you might just want to have an array of input objects with some properties, and then ng-repeat over that array like following:
Controller:
$scope.inputs = [];
$scope.addMore = function() {
$scope.inputs.push({
id: $scope.inputs.length,
text: "Initial text here"
})
};
HTML:
<input ng-repeat="input in inputs" ng-model="inputs[$index].text">
<button ng-click="addMore()">Add more!</button>
What you want to do is to create an array of input button.
display your input array :
<div ng-repeat="item in items"><input type="text" ng-model="item.value"><div>
attach a function to the ng-click of your button :
<button ng-click="addMore()">Add More</button>
and then define your array in controller :
$scope.items = [];
$scope.addMore = function () {
$scope.items.push({
value:'default'
});