Changing multi select element with Angularjs - angularjs

There is a multi select element in my page.
<div class="form-group">
<select ng-show="'#Model.IsWinnerFilterVisible'" class="selectpicker" multiple title="Kazanan" ng-model="MainWinnerFilterSelected" id="ddl_winnerid"
data-ng-options="MainWinnerFilter.Id as MainWinnerFilter.Name for MainWinnerFilter in MainWinnerFilters"></select>
</div>
<div class="form-group">
<select ng-show="'#Model.IsReasonFilterVisible'" class="form-control" title="İlgilenilmeme Nedeni" ng-model="MainReasonFilterSelected" id="ddl_reasonid" ng-init="MainReasonFilterSelected= #Model.SelectedReason"
data-ng-options="MainReasonFilter.Id as MainReasonFilter.Name for MainReasonFilter in MainReasonFilters">
<option value="">İlgilenilmeme Nedeni</option>
</select>
</div>
And i can load this first with the code below
$scope.MainWinnerFilterSelected = #Html.Raw(Json.Encode(Model.SelectedWinner));
I want to reload this element with a new data but it dosent work.
$scope.loadReasonAndWinner= function() {
var productGroupFilters=$scope.productGroupFilterSelected;
var res = $http.post('#Url.Action("GetWinnerAndReasonList", "Details")', {'selectedProductGroup':productGroupFilters});
res.success(function(data, status) {
$scope.MainWinnerFilters=data.WinnerList;
$scope.MainReasonFilters=data.NotInterestingReasonList;
});
res.error(function(data, status) {
$scope.addError("alert-danger","Bir Hata oluştu.","Error");
});
}
In controller;
[HttpPost]
public ActionResult GetWinnerAndReasonList(int SelectedProductGroup)
{
var detail = new DetailsModel();
detail.SelectedProductGroup = SelectedProductGroup;
var winnerList = BiddingService.RetrieveWinners(null, VariableHelper.ListOf(detail.SelectedProductGroup));
detail.WinnerList = BiddingService.TranslateToFilter(winnerList);
var notInterestedActionStatus = new List<int>() { VariableHelper.Int(ActionStates.NotInterested) };
var notInterestingReasonList = BiddingService.RetrieveActionReason(notInterestedActionStatus, VariableHelper.ListOf(detail.SelectedProductGroup));
detail.NotInterestingReasonList = BiddingService.TranslateToFilter(notInterestingReasonList);
return Json(detail);
}
New data comes true and it works with combobox (MainReasonFilter) but it dosent change the items in multiselect element(MainWinnerFilter). Any idea with that?

Related

Remove select options based on button click in angular js

In my app i have a select html which has following options
"Addition","Deletion","Duplicate","Member Duplicate"
Above drop down page is common for both add and edit screen. As of now if we come from any addition click or edit click drop-down has all options. (Note: drop-down binds at the time of loading page itself. we will show/hide depending on click)
As per new requirement I need to remove all other options except "Addition" in addition click and remove "Addition" option in edit click.
select html:
<select name="ReasonID" required ng-model="member.ReasonID" class="form-control" ng-options="reason.ID as reason.Description for reason in reasons |orderBy: reason.Description"></select>
Js
$scope.manageMember = function (member) {
$scope.showGrid = false;
$scope.showForm = true;
reset();
$scope.memberTemp = member;
angular.extend($scope.member, member); };
Please let me know if you need more details from my end.
Update :
Here the full sample code and working demo with dummy data.
HTML
<div ng-app>
<h2>Todo</h2>
<div ng-controller="TodoCtrl">
<select name="ReasonID" required ng-model="member.ReasonID" class="form-control" ng-options="reason.ID as reason.Description for reason in reasons |orderBy: reason.Description"></select>
<br/>
<input type="button" ng-click="manageMember(undefined)" value="add"/>
<input type="button" ng-click="manageMember('bla bla bla')" value="edit"/>
</div>
</div>
JS
function TodoCtrl($scope) {
$scope.reasons = [{ID:1,Description :"Addition"}, {ID:2,Description :"Deletion"},{ID:3,Description :"Duplicate"},{ID:4,Description :"Member Duplicate"}];
var reasonsTemp =angular.copy($scope.reasons);
$scope.manageMember = function (member) {
console.log(reasonsTemp)
$scope.reasons=reasonsTemp;// assign global object to model
$scope.showGrid = false;
$scope.showForm = true;
$scope.memberTemp = member;
var EditArray=[];
for(var i = 0 ; $scope.reasons.length>i;i++)
{
if($scope.reasons[i].Description === ($scope.memberTemp == undefined ? "Addition" : "bla bla bla"))// condition for is this addition or not
{
EditArray = $scope.reasons[i];
break;
}
else // if is it not addition, then addition only offect that object. because we were already assigned original value globally
{
if($scope.reasons[i].Description!=="Addition")
{
EditArray.push($scope.reasons[i])
}
}
}
$scope.reasons=EditArray;
console.log($scope.reasons);
}
}
Working Demo On console window
Try this,
HTML
<select ng-model="selectedOption">
<option ng-show="reason.show" ng-repeat="reason.ID as reason.Description for reason in reasons |orderBy: reason.Description">{{reason.ID}}</option>
</select>
JS
$scope.manageMember = function (member) {
$scope.showGrid = false;
$scope.showForm = true;
reset();
$scope.memberTemp = member;
angular.extend($scope.member, member);
if(member){
for(var i = 0 ; $scope.reasons.length>i;i++)
{
$scope.reasons[i].show = true;
if($scope.reasons[i].ID == "Addition"){$scope.reasons[i].show = false;}
}
}else{
for(var i = 0 ; $scope.reasons.length>i;i++)
{
$scope.reasons[i].show = false;
if($scope.reasons[i].ID == "Addition"){$scope.reasons[i].show = true;}
}
}
}
Suppose you have two buttons as,
<input type="button" ng-click="toAdd=true">Add</input>
<input type="button" ng-click="toAdd=false">Edit</input>
And the select box code should be like,
<select ng-model="selectedOption">
<option ng-show="toAdd">Addition</option>
<option ng-show="!toAdd">Deletion</option>
<option ng-show="!toAdd">Duplicate</option>
<option ng-show="!toAdd">Member Duplicate</option>
</select>
Hope this helps.

highlighting previous row after ng-click

I have a dropdownlist which contains brand ids. acccording to the id im fetching corresponding products and showing it in a table. There are two buttons in each row that move the products up and down basically by interchanging the ranks. now i am able to do all the functionality of interchanging and re binding.The row is selected when it is clicked. my only problem is i am not able to select the row after it has moved up or down.
<div ng-app="myapp" ng-controller="prodctrl">
<select id="BrandDropdown" class="InstanceList" ng-change="GetBrandProd()" ng-model="Products">
<option>Select Brand</option> //Sample Data
<option value=1>Brand 1<option>
<option value=2>Brand 2<option>
</select>
<table id="prodtab" ng-model="Products">
<tr ng-repeat="P in Products track by $index" ng-click="setselected($index)" class="{{selected}}">
<td>{{P.Id}}</td>
<td>{{P.Rank}}</td>
<td>{{P.Name}}</td>
<td>
<input type="button" value="Move Up" id="moveup" ng-click="getval(P,$index)" /></td>
<td>
<input type="button" value="Move Down" /></td>
</tr>
</table>
</div>
this is the angularjs code
<script>
var app = angular.module('myapp', []);
var prod = null;
var mveup = null;
var mvedwn = null;
var ind = null;
app.controller('prodctrl', function ($scope, $http) {
//getting products for each brand
$scope.GetBrandProd = function () {
cursel = "B";
var Id = $('#BrandDropdown').val();
fetchtype = Id;
brid = Id;
$http({
method: "GET",
url: "/Home/GetProdBrand",
params: {
id: Id
}
})
.success(function (response) {
var data = response;
$scope.Products = data;
prod = data;
});
};
//changing color of row when clicked
$scope.setselected = function (index) {
if ($scope.lastSelected) {
$scope.lastSelected.selected = '';
}
if (mveup == null) {
this.selected = 'trselected';
$scope.lastSelected = this;
}
else {
mveup = null;
//this.selected = '';
$(this).closest('tr').prev().prop('Class', 'trselected');
}
};
//function to move product up in ranking
$scope.getval = function (p, index) {
var Idcur = p.Id;
var Rankcur = p.Rank;
ind = index;
if ($scope.Products[index - 1] != null) {
var IdPrev=$scope.Products[index - 1].Id;
var Rankprev = $scope.Products[index - 1].Rank;
mveup = null;
$scope.lastSelected = this;
if (cursel == "B") {
fetchtype = brid;
}
else if (cursel == "C") {
}
mveup = true;
$http({
method: "GET",
url: "/Home/MoveProd",
params: {
Curid: Idcur,
CurRank: Rankcur,
ChngId: IdPrev,
ChngRnk: Rankprev,
Type: cursel,
Id: fetchtype
}
})
.success(function (response) {
// ranks are interchanged and the data is returned.
var data = response;
$scope.Products = data;
prod = data;
});
}
}
})
</script>
It seems, the way you are handling the row selection is not correct.
I have just changed the way of handling selection here.
<tr ng-repeat="P in Products track by $index" ng-click="setselected($index)" ng-class="{selected: selectedIndex == $index}">
//JS
$scope.setselected = function(index) {
$scope.selectedIndex = index;
};
Also, I have done a plunker with some sample values to imitate your requirement, you can ask more, if it is not fit to your requirement.
Plunker
You already have the id of the product that was clicked on (I think from looking at your code, it's Idcur), so you could loop over your results in the success block of the /Home/MoveProd GET request and set the record with the matching id to selected? Something like
var products = $scope.Products.filter(function(product) {
return product.id == Idcur;
})
if (products && products.length > 0) {
products[0].selected = 'trselected';
}
then, in your page, just update the ng-repeat slightly to pick the selected class from the product, instead of the scope, so:
<tr ng-repeat="P in Products track by $index" ng-click="setselected($index)" class="{{selected}}">
becomes
<tr ng-repeat="P in Products track by $index" ng-click="setselected($index)" class="{{P.selected}}">
or something like that :)

Get model array values in controller's service

I've been facing an issue since couple of hours. My view template looks like-
<div class="row" ng-repeat="row in CampaignsService.getRows().subItems track by $index">
<div class="col-sm-2">
<select class="form-control dropDownPercent" ng-model="CampaignsService.dropDownPercent[{{CampaignsService.selectCounter}}]" ng-change="CampaignsService.wow(CampaignsService.dropDownPercent, $index)" ng-options="o as o for o in CampaignsService.showPercentDropDown().values">
</select>
</div>
<div class="col-sm-2" style="line-height: 32px">
of visitors send to
</div>
<div class="col-sm-4">
<select class="form-control" ng-model="campaignSelect" ng-options="campaign.Campaign.id as campaign.Campaign.title for campaign in CampaignsService.getRows().items">
<option value=""> Please select </option>
</select>
</div>
<div class="col-sm-4">
<a class="btn btn-default" target="_blank" href="">Show campaign</a>
</div>
Variable CampaignsService.selectCounter is a counter variable and declared in service but when I'm going to use ng-model="CampaignsService.dropDownPercent[{{CampaignsService.selectCounter}}]" it gives me error -
Error: [$parse:syntax] Syntax Error: Token '{' invalid key at column 35 of the expression [CampaignsService.dropDownPercent[{{CampaignsService.selectCounter}}]] starting at [{CampaignsService.selectCounter}}]]
And when I use ng-model="CampaignsService.dropDownPercent['{{CampaignsService.selectCounter}}']" it does not give any error but it takes this variable as string.
My question is how could I create a model array and get model's array values in my service ?? I read many questions in stack community and none of the trick work for me. My service under my script, is
.service('CampaignsService', ['$rootScope', 'AjaxRequests', function ($rootScope, AjaxRequests) {
this.dropDownPercent = [];
this.selectCounter = 0;
var gareeb = [];
this.showPercentDefault = 100;
// this.campaignsData = [];
this.$rowsData = {
items: [], //array of objects
current: [], //array of objects
subItems: [] //array of objects
};
this.getRows = function () {
return this.$rowsData;
}
this.addNewRow = function () {
var wowRow = {}; //add a new object
this.getRows().subItems.push(wowRow);
this.selectCounter++;
gareeb.push(0);
}
this.calculatePercentages = function (index) {
angular.forEach(this.getRows().current, function (data, key) {
if (key == index) {
console.log(data);
}
})
}
this.showPercentDropDown = function ($index) {
var balle = 0;
var start;
angular.forEach(gareeb, function (aha, keywa) {
balle += aha;
})
var last = 100 - balle;
var final = [];
for (start = 0; start <= last; start += 10) {
final.push(start);
}
return this.values = {
values: final,
};
}
this.wow = function (valueWa, keyWa) {
console.log(this.dropDownPercent);
gareeb[keyWa] = valueWa;
this.changePercentDropDown();
}
this.changePercentDropDown = function () {
var angElement = angular.element(document.querySelector('.dropDownPercent'));
angular.forEach(angElement, function (data, key) {
console.log(data);
})
}
}])
Target model structure should be
ng-model="CampaignsService.dropDownPercent[1]"
ng-model="CampaignsService.dropDownPercent[2]"
ng-model="CampaignsService.dropDownPercent[3]"
A big thanks in advance.
Since you are in context of the Angular expression, you don't need interpolation tags {{...}}. So ngModel directive should look like this:
ng-model="CampaignsService.dropDownPercent[CampaignsService.selectCounter]"

How to set multiple attributes in model (Backbone.js) using strings as keys?

I have a similar question like this: setting backbone models but I need to set multiple attributes, not only one.
So, I have a model in which someone can add custom attributes and I have problem setting them, because if I do it this way:
parameter.set({
name: nameValue,
value: valueValue,
description: descriptionValue
});
where name, value and description are string values, backbone is creating a new attribute by the name of "name", "value" and "description", but I actually need them to be values of the "name" etc.
If I try to do it this way:
parameter.set(name, nameValue);
parameter.set(value, valueValue);
parameter.set(description, descriptionValue);
backbone creates only the last line: parameter.set(description, descriptionValue);
the same thing happens when I try to do it this way:
parameter.attributes[name] = nameValue;
parameter.attributes[value] = valueValue;
parameter.attributes[description] = descriptionValue;
so, for example, let's say I have this HTML code:
<input type="text" id="name"/>
<input type="text" id="nameValue"/>
<input type="text" id="value"/>
<input type="text" id="valueValue"/>
<input type="text" id="description"/>
<input type="text" id="descriptionValue"/>
where:
var name = this.$('#name');
var nameValue = this.$('#nameValue');
var value = this.$('#value');
var valueValue = this.$('#valueValue');
var description = this.$('#description');
var descriptionValue = this.$('#descriptionValue');
You can add them like:
var name = this.$('#name').val();
var nameValue = this.$('#nameValue').val();
var value = this.$('#value').val();
var valueValue = this.$('#valueValue').val();
var description = this.$('#description').val();
var descriptionValue = this.$('#descriptionValue').val();
var params = {};
if (name) {
params[name] = nameValue;
}
// the same for other attributes
// ....
// And at the end
model.set(params);
If statement will ensure that attribute names exists. And then collect them into an empty object. At the end set them at once.
Update
Below you can find working example of your issue. Fill the inputs and then click submit to stringify the object you wish to construct.
var MyForm = Backbone.View.extend({
el: '#test',
events: {
"click .submit": "showObject"
},
showObject: function(e) {
e.preventDefault();
var name = this.$('#name').val();
var nameValue = this.$('#nameValue').val();
var value = this.$('#value').val();
var valueValue = this.$('#valueValue').val();
var description = this.$('#description').val();
var descriptionValue = this.$('#descriptionValue').val();
var params = {};
if (name) {
params[name] = nameValue;
}
if (value) {
params[value] = valueValue;
}
if (description) {
params[description] = descriptionValue;
}
this.model.set(params);
this.$('.test-object').text(JSON.stringify(this.model.toJSON()));
}});
var TestModel = Backbone.Model.extend({});
var myForm = new MyForm({model: (new TestModel()) });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.2/backbone.js"></script>
<div id="test">
<input type="text" id="name"/>
<input type="text" id="nameValue"/>
<input type="text" id="value"/>
<input type="text" id="valueValue"/>
<input type="text" id="description"/>
<input type="text" id="descriptionValue"/>
<div class="test-object"></div>
<button class="submit">Show object</button>
</div>

angularjs multiple selected item does consist of a string and not an object

I have created a select tag with multiple to show it as a listbox and not dropdown.
I have a property which should hold the selected schoolclass which consists of multiple properties like: id, schoolclass , subject, schoolclassIdentifier and color.
When I select now an item in the listbox and press the delete button the $scope.activeStep.selectedSchoolclassCodes array contains one string like "Math10b" actually the selectedSchoolclassCodes array should contain an object created from the above properties.
Why is my selected object wrong?
HTML
<div class="col-md-6">
<select size="10" class="form-control col-md-6" multiple ng-model="activeStep.selectedSchoolclassCodes">
<option class="co-md-6" ng-repeat="item in activeStep.schoolclasses" style="background: rgb({{item.color}})" value="{{item.schoolclassCode}}">{{item.schoolclassCode}}</option>
</select>
</div>
CONTROLLER
'use strict';
angular.module('iplanmylessons').controller('EditSchoolclassCodeWizardStepController', function ($scope, wizardDataFactory, SchoolclassCodeViewModel) {
$scope.activeStep.schoolclassCodeColors = [
'255,165,0',
'255,255,0',
'145,240,140',
'0,128,0',
'170,210,230',
'255,190,200',
'240,130,240',
'100,100,255',
'210,210,210',
'255,0,0'
];
$scope.activeStep.selectedSchoolclassCodes = wizardDataFactory.schoolclassCodesAdded[0];
$scope.activeStep.newSchoolclass = "";
$scope.activeStep.newSubject = "";
$scope.activeStep.newSchoolclassIdentifier = "";
$scope.activeStep.schoolclasses = wizardDataFactory.schoolclassCodesAdded;
$scope.activeStep.schoolclassCodeColorsIsOpen = false;
$scope.activeStep.selectedSchoolclassCodeColor = null;
$scope.activeStep.deleteSchoolclassCode = function () {
for (var i = 0; i < $scope.activeStep.selectedSchoolclassCodes.length; i++) {
var index = Enumerable.from( wizardDataFactory.schoolclassCodesAdded).indexOf(function (s) {
return s.schoolclassCode === $scope.activeStep.selectedSchoolclassCodes[i].schoolclassCode;
});
wizardDataFactory.schoolclassCodesAdded.splice(index, 1);
}
$scope.activeStep.selectedSchoolclassCodes = null;
};
$scope.activeStep.schoolclassCode = function () {
return $scope.activeStep.newSubject + $scope.activeStep.newSchoolclass + $scope.activeStep.newSchoolclassIdentifier;
};
$scope.activeStep.setSchoolclassCodeColor = function (item) {
$scope.activeStep.selectedSchoolclassCodeColor = item;
$scope.activeStep.schoolclassCodeColorsIsOpen = false;
};
});
Have you try ng-options? This post has a good explanation of select/ ng-options with array of objects.
Hope it can help.

Resources