How to get alert when Ichange dropdown options using angularjs - html

This is my dropddown menu, when I change the option will get alert its working, but when i select again on the same option i didnt get alert.How it posiible
index.html
<body ng-app="demoApp">
<div ng-controller="DemoController">
<div>
<select ng-model="currentlySelected" ng-options="opt as opt.label for opt in options" ng-change="logResult()">
</select>
The value selected is {{ currentlySelected.value }}.
</div>
</div>
</body>
app.js
angular.module('demoApp', []).controller('DemoController', function($scope) {
$scope.options = [
{ label: 'one', value: 1 },
{ label: 'two', value: 2 }
{ label: 'three', value: 3 }
{ label: 'four', value: 4 }
{ label: 'five', value: 5 }
];
$scope.currentlySelected = $scope.options[1];
$scope.logResult = function() {
alert($scope.currentlySelected);
}
});
What I expect is if I select "two" twice i need to alert twice. Is this possible or should I be using a different directive for this?

No, it's not possible. onchange event is fired when selection changes, not when you make a selection. So unless you choose different option, it's not going to fire.
If you need this behaviour I would suggest using one of the custom select solutions, even custom CSS based select would work. Then you could bind to onclick event instead of onchange.

Related

How to manually focus input

I want to replicate a common item list renaming feature, where you have a list of layers and if you double click a layer, it changes the layer item to an input and that input is automatically focused with its text selected as well.
In my example, I am not able to focus() the DOM element by its ref because it says it is not defined. It only works if I click a second time on the element once its changed to an input. How do I set this autofocus?
<div v-for="(item, i) in items">
<div #click="changeToInput(i)" v-if="!item.input">{{item.name}}</div>
<input ref="input" v-model="item.name" onfocus="select()" v-else>
</div>
changeToInput(i) {
this.items[i].input = true;
//this.$refs.input.focus()
}
Here is the complete example : https://codesandbox.io/s/reverent-khayyam-2x8mp?file=/src/App.vue:481-573
Two solutions:
First one: uses v-if + this.$nextTick:
v-if will insert/destroy the component when the binding expression is true/false, so in current cycle, input hasn't been in Dom tree. You have to use nextTick to wait for next cycle to get the Dom element of Input. And this.$refs.input will be one array based on how many v-if=true, so you have to filter out the this.items to find out correct index (that is why I used one combination of Array.slice and Array.filter).
Updated: The order of the elements of this.$refs.input1 is the order VNode is created. For example: clicks input2 -> input3 -> input1, the order of this.$refs.input1 is [2, 3, 1], not [1, 2, 3].
Second one: uses v-show + this.$nextTick:
It will make things easier, because v-show only update the css styles for Dom elements, it will not add/remove component instance (Vnode) from VNode tree. So the this.$refs.input will always equal this.items.length.
new Vue ({
el:'#app',
data() {
return {
items1: [
{ name: "Joe", input: false },
{ name: "Sarah", input: false },
{ name: "Jeff", input: false }
],
items2: [
{ name: "Joe", input: false },
{ name: "Sarah", input: false },
{ name: "Jeff", input: false }
],
refSort: {}
};
},
methods: {
changeToInput1(i) {
this.items1[i].input = true;
let refCount = (this.$refs.input1 && this.$refs.input1.length) || 0
refCount < this.items1.length && (this.refSort[i] = refCount)
this.$nextTick(() => {
// the purpose uses this.refSort is record the order of this.$refs.input (Its order is same as the creating order of Ref), you can uncomment below line to see the root cause
//console.log(this.$refs.input1[0] && this.$refs.input1[0].value, this.$refs.input1[1] && this.$refs.input1[1].value, this.$refs.input1[2] && this.$refs.input1[2].value)
this.$refs.input1[this.refSort[i]].focus()
})
},
changeToInput2(i) {
this.items2[i].input = true;
this.$nextTick(() => this.$refs.input2[i].focus())
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
<h3>Uses v-if: <p>{{items1}}</p></h3>
<div v-for="(item, i) in items1">
<div #click="changeToInput1(i)" v-if="!item.input">{{item.name}}</div>
<input ref="input1" v-model="item.name" onfocus="select()" v-else>
</div>
<h3>Uses v-show: <p>{{items2}}</p></h3>
<div v-for="(item, i) in items2">
<div #click="changeToInput2(i)" v-show="!item.input">{{item.name}}</div>
<input ref="input2" v-model="item.name" onfocus="select()" v-show="item.input">
</div>
</div>

How to get multiple radio buttons to work in angular2?

I have a array of json, something similar to this:
questions =
[
{
title: Your section is?
choices: [
{
id: 1,
label: "TestA"
},
{
id=2,
label: "TestB"
}
]
},
{
title: Your major is?
choices: [
{
id=3,
label: "Medicine"
},
{
id=4,
label: "Engineering"
}
]
}
]
My html:
<div *ngFor="let choice of questions">
<div *ngFor="let choice of questions.choices;let i=index">
<div class="radio-group" (click)="onSelectChoice(choice.id)">
<input type="radio" class="hide" name="choiceElements" [value]="choice.id" id="choice.label" formControlName="choiceElements">
<label [class.selected]="choice.id === selctedRadio" for="{{choice.label}}" class="" >{{choice.label}}</label>
</div>
</div>
</div>
My TS:
selctedRadio: '';
onSelectChoice(selctedChoice: any){
this.selctedRadio = selctedChoice;
}
So, in html I need two questions, each question having two buttons, for each question I should be able to select one radio button.
But in my case, I am able to select only one radio button and when I go to second question the selected first question becomes unselected.
Let me know how I can be able to select one radio answer from each question.
Your radio buttons must have the same name if and only if they belong to the same group.
You will have to find a way to create a unique-per-group name.
By the way, this is not angular specific, it's just how radio buttons work in plain HTML.
however, for more info about how to handle radio buttons in angular, you can check this :
Angular2 ReactiveFormsControl: how to bind radio buttons?
Angular2 - Radio Button Binding

md-chips with md-select in multi select mode

When I am trying to generate md-chips on selecting multiple values from md-select, It is not working. Does md-chips works only with autocomplete analyser and input field?
<md-chips ng-model="launchAPIQueryParams.type">
<md-select name="launchCalType" ng-model="launchAPIQueryParams.type"
multiple="true" placeholder="Launch Type"
md-on-close='applylaunchFilter("type")'>
<md-option ng-repeat="typeOption in launchTypeOptions" ng-value="typeOption[1]">
{{typeOption[0]}}
</md-option>
</md-select>
</md-chips>
The short answer: No.
<md-chips> component will only takes <input> or <md-autocomplete> into its transcluded context.
However, the same thing can be achieved with md-autocompelet.
The key is set md-min-length on <md-autocomplete> to 0 so it will auto show the menu just like what a <md-select> menu would be.
Here's an example:
// controller.js
angular
.moduel('mdChipsDemo', [])
.controller('MdChipsDemoCtrl', function() {
var vm = this;
vm.selectedOption = '';
vm.searchText = '';
vm.launchAPIQueryParams = {
types: [],
};
vm.launchTypeOptions = [
{name: 'Op1', value: 1},
{name: 'Op2', value: 2},
{name: 'Op3', value: 3},
{name: 'Op4', value: 4},
];
});
// template.html
<div ng-app="mdChipsDemo" ng-controller="MdChipsDemoCtrl as vm">
<md-chips ng-model="vm.launchAPIQueryParams.types">
<md-autocomplete
md-selected-item="vm.selectedOption"
md-search-text="vm.searchText"
md-items="typeOption in vm.launchTypeOptions"
md-item-text="typeOption.name"
md-min-length="0"
placeholder="Search for a launchTypeOptions">
<span md-highlight-text="vm.searchText">{{typeOption.name}}</span>
</md-autocomplete>
<md-chip-template>
<span>{{$chip.name}}</span>
</md-chip-template>
</md-chips>
</div>
If your ultimate goal is to have multiple select ability, <md-autocomplete> also expose <md-item-template> where you can put your <md-select> in. Check the doc for md-autocomplete and you will see.
Or if you really insist on using <select>, there's an 3rd-party component on npm calls md-chips-select which does what you want.
https://www.npmjs.com/package/md-chips-select

How to change appearance of the state type drop down when disabled mode

We have two drop downs. Based on the first dropdown event changed the second drop down values are getting populated.
How to change appearance of the 2nd type drop down such that it should be different for both enabled and disabled state?
In both drop down they look like enabled but until we select the country the states not loaded any way .. The select CSS was behaving as excepted in IE but not in Chrome. It was looking as enabled in Chrome.
//***********//
button,
input,
optgroup,
select,
textarea {
margin: 0;
font: inherit;
color: inherit;
}
When I removed the Color inherit from boot strap It makes the difference.How to override the style sheet which effecs the color to the state dropdown in the customized CSS
<div class="item1" id="countries">
<div class="selectbox">
<select data-bind="options: Countries,
optionsText: $data,
optionsValue: $data,
value: SelectedCountry,
event: { change: $parent.CountryActionChanged }">
</select>
</div>
</div>
<div class="item2" id="states">
<div class="selectbox">
<select data-bind="options: States,
optionsText: 'Name',
optionsValue: 'Id',
value: SelectedStateType,
event: { change: $parent.StateActionChanged },
enable: $parent.IsStateType"
>
</select>
</div>
</div>
You haven't provided a full repro. When I tried to stub out the things you omitted, I ran in to various problems. So I've decided to tell you how you could do things slightly different, in a way that will also solve the enable binding issue. Here it is:
var ViewModel = function() {
var self = this;
self.countries = [
{ name: "US", states: ["NY", "CA", "etc"] },
{ name: "Monaco", states: [] },
{ name: "Vatican", states: [] }
// etc
];
self.selectedCountry = ko.observable();
self.selectedState = ko.observable();
self.availableStates = ko.computed(function() {
if (!!self.selectedCountry()) {
return self.selectedCountry().states;
}
return [];
});
self.selectedCountryHasStates = ko.computed(function() {
return self.availableStates().length > 0;
});
};
ko.applyBindings(new ViewModel());
select { min-width: 15em; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div class="item1" id="countries">
<div class="selectbox">
<select data-bind="
options: countries,
optionsText: 'name',
value: selectedCountry">
</select>
</div>
</div>
<div class="item2" id="states">
<div class="selectbox">
<select data-bind="
options: availableStates,
value: selectedState,
enable: selectedCountryHasStates">
</select>
</div>
</div>
Things to note:
Don't use the event binding unless you really, really have to. Instead, use computed functions so your view models change dynamically based on the selections made by users.
(Subjective) Reserve PascalCase for constructor functions, and use camelCase for members and variables.
Base the enable status on whether there are states or not. Do this in a seperate computed so you can unit test its logic.
Try to bind dropdowns to complex object (e.g. countries themselves), this makes your view models use the OO features of constructor functions / javascript in a way that makes your code a lot more readable. It also slims down your data-bind attributes a lot.

Simply showing a component Only if another component is showing - Ext JS

So I have a hidden container item:
id: 'category_search', hidden: true, ...
And another hidden panel:
{ xtype: 'panel', id: 'mylist', hidden: true ...
Here i have a controller to show category search ONLY when mylist is Not hidden - handled by the click of a button categorized_search:
catSearch: function() {
var grid = Ext.getCmp('mylist');
if(grid.isHidden){ //checking to see if the component is hidden
console.log('Please enter a search');
}
else
{
Ext.getCmp('category_search').show(); //Shows category search
}
}
When I click my categorized_search button, it does not display when mylist is showing, and will display when mylist is not showing. How can I fix this?
Cheers!
AbstractComponent.isHidden() and AbstractComponent.isVisible() are functions, not properties. Add parentheses to your if statement.
http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.AbstractComponent-method-isHidden