Working with subset of Angular JS model - javascript

Here is my model:
var nav = [{
label: 'Pages',
value: '#',
toggle: 'dropdown', // set this to '' when the menu has no children
children: [{
label: 'Home',
value: 'home'
}, {
label: 'Left Nav',
value: 'leftnav'
}, {
label: 'Two-Panel Selector',
value: 'two_panel_selector'
}]
}, {
label: 'Components',
value: '#',
toggle: 'dropdown',
children: [{
label: 'Lists & Tables',
value: 'lists_tables'
}]
}, {
label: 'Elements',
value: '#',
toggle: 'dropdown',
children: [{
label: 'Text',
value: 'elements?section=Text'
}, {
label: 'Buttons',
value: 'elements?section=Buttons'
}, {
label: 'Alerts',
value: 'elements?section=Alerts'
}, {
label: 'Inputs',
value: 'elements?section=Inputs'
}, {
label: 'Icons',
value: 'elements?section=Icons'
}, {
label: 'Sample Grid',
value: 'elements?section=Grid'
}, ]
}];
return {
getNavData: function() {
return nav;
}
};
I would like to work with the "Elements" children in a list. This works fine, but I am wondering if there's a way without using the array index as I have done:
div class="list-group">
<a class="list-group-item" ng-repeat="l in navData[2].children" ng-class="{'active': l.label == submenu}" ng-click="select(l.label)">{{l.label}}</a>
</div>

You could search for the element in your array like this:
<a ng-repeat="l in elementsChildren()"></a>
and in your controller:
$scope.elementsChildren() = function() {
for(var i = 0; i < nav.length; i++) {
if (nav[i].label === 'Elements')
return nav[i].children;
return [];
}
This means that if 'Elements' is moved within the array, your view won't break. However, this is more expensive. You will now be iterating over the array to find 'elements' (O(n)), as opposed to indexing directly into your array (O(1)).

Related

Sencha 6.5 (modern) how to dynamically change the items in a menu in a title bar?

Well considering a grid I create in my application:
{
xtype: 'ordergrid',
itemId: 'ordergrid',
titleBar: {
shadow: false,
items: [{
align: 'right',
xtype: 'button',
text: 'Update status',
stretchMenu: true,
menu: {
itemId: 'status_menu',
defaults: {
handler: 'updateStatus'
},
indented: false,
items: [{
text: 'test1',
value: 'test1'
}, {
text: 'test2',
value: 'test2'
}, {
text: 'test3',
value: 'test4'
}]
}
}]
},
With ordergrid being defined with:
extend: 'Ext.grid.Grid',
xtype: 'ordergrid',
I wish to modify the items of the menu dynamically. I've first tried doing this through a store:
menu: {
itemId: 'status_menu',
defaults: {
handler: 'updateStatus'
},
indented: false,
store: { type: 'status' }
Though this doesn't seem to work. Then I tried accessing this menu through a component query, during the init function of some controller:
Ext.define('BinkPortalFrontend.view.main.OrderController', {
extend: 'Ext.app.ViewController',
alias: 'controller.order',
init: function () {
console.log('..... initializing ......');
const menus = Ext.ComponentQuery.query('ordergrid #status_menu');
const menu = menus[0];
menu.setItems([{
text: 'some',
value: 'some'
}, {
text: 'new',
value: 'mew'
}]);
},
};
However this returns an error: "Cannot read property 'setItems' of undefined"
Debugging shows the obvious problem: it doesn't find any menu.
What's more, even a "catch all" query like
Ext.ComponentQuery.query('menu');
or
Ext.ComponentQuery.query('#status_menu');
Shows an empty array: so what's going on? (I most definitely see the menu from its initial load).
There is one reason your menu is not created. Menu will created whenever button will tap or whenever getMenu() method get called.
If you want to get your menu using Ext.ComponentQuery.query(), so for this you need to do use initialize event of button and forcefully create menu using getMenu() method like below :-
{
xtype: 'button',
text: 'Update status',
stretchMenu: true,
menu: {
itemId: 'status_menu',
indented: false,
items: [{
text: 'test1',
value: 'test1'
}, {
text: 'test2',
value: 'test2'
}, {
text: 'test3',
value: 'test4'
}]
},
listeners: {
initialize: function(btn) {
Ext.defer(function() {
// This will print undefined because menu have not created
console.log(Ext.ComponentQuery.query('#status_menu')[0]);
//When we use getMenu method it will create menu item
btn.getMenu().hide();
// This will print menu component
console.log(Ext.ComponentQuery.query('#status_menu')[0]);
}, 10)
}
}
}
Another way you can use getMenu() method of button. It will return the menu component.
In this FIDDLE, I have created a demo using grid, button and menu. I hope this will help/guide you to achieve your requirement.
CODE SNIPPET
Ext.application({
name: 'Fiddle',
launch: function () {
var store = Ext.create('Ext.data.Store', {
fields: ['name', 'email', 'phone'],
data: [{
'name': 'Lisa',
"email": "lisa#simpsons.com",
"phone": "555-111-1224"
}, {
'name': 'Bart',
"email": "bart#simpsons.com",
"phone": "555-222-1234"
}, {
'name': 'Homer',
"email": "home#simpsons.com",
"phone": "555-222-1244"
}, {
'name': 'Marge',
"email": "marge#simpsons.com",
"phone": "555-222-1254"
}]
});
Ext.create('Ext.grid.Grid', {
title: 'Change menu items dynamically',
titleBar: {
shadow: false,
items: [{
align: 'right',
xtype: 'button',
text: 'Update status',
stretchMenu: true,
itemId: 'statusbtn',
menu: {
itemId: 'status_menu',
defaults: {
// handler: 'updateStatus'
},
indented: false,
items: [{
text: 'test1',
value: 'test1'
}, {
text: 'test2',
value: 'test2'
}, {
text: 'test3',
value: 'test4'
}]
},
listeners: {
initialize: function (btn) {
Ext.defer(function () {
// This will undefined because menu has not been created
console.log(Ext.ComponentQuery.query('#status_menu')[0]);
//When we use getMenu method it will create menu item
btn.getMenu().hide();
// This will menu component
console.log(Ext.ComponentQuery.query('#status_menu')[0]);
}, 10)
}
}
}, {
xtype: 'button',
align: 'right',
text: 'Change Items',
handler: function (btn) {
var newItems = [];
store.each(rec => {
newItems.push({
text: rec.get('name'),
value: rec.get('name')
})
});
/*
* You can also get menu using button
* btn.up('titlebar').down('#statusbtn').getMenu().setItems(newItems);
*/
Ext.ComponentQuery.query('#status_menu')[0].setItems(newItems);
Ext.toast('Menu items has been change. Please check', 2000);
}
}]
},
store: store,
columns: [{
text: 'Name',
dataIndex: 'name',
width: 200
}, {
text: 'Email',
dataIndex: 'email',
width: 250
}, {
text: 'Phone',
dataIndex: 'phone',
width: 120
}],
height: 200,
layout: 'fit',
fullscreen: true
});
}
});
For more details about component you can also see this ComponentManager

How to add a 'tabindex' for radio buttons in angular formly

I have a requirement to add a specific tabindex to radio button in my formly form.
I can do it for text field but not for radio buttons, below is the sample code, any help is appreciated -
Tried adding the tabindex=1 at three places, above templateOptions, inside templateOptions and inside options, none of them works to get the focus.
{
name: 'feedbackType',
key: 'feedbackType',
type: 'radio',
id: 'feedbackType',
//tabindex:'1',
templateOptions: {
label: Constant.feedbackForm.typeField,
for:'feedbackType',
required: true,
focus: true,
//tabindex:'1',
options: [{
name: 'Idea1',
value: 'Idea1',
//tabindex:'1'
}, {
name: 'Idea2',
value: 'Idea2'
}, {
name: 'Idea3',
value: 'Idea3'
}]
}
},
Here you go. You'll want to use ngModelElAttrs. Like this
{
name: 'feedbackType',
key: 'feedbackType',
type: 'radio',
id: 'feedbackType',
ngModelElAttrs: {
tabindex: '1'
},
templateOptions: {
label: EaseConstant.feedbackForm.typeField,
for:'feedbackType',
required: true,
focus: true,
options: [{
name: 'Idea1',
value: 'Idea1',
}, {
name: 'Idea2',
value: 'Idea2'
}, {
name: 'Idea3',
value: 'Idea3'
}]
}
},
If you want it to be dynamic, then you can do:
ngModelElAttrs: {
tabindex: '{{to.tabindex}}' // to is a shortcut for `options.templateOptions`
},
expressionProperties: {
'templateOptions.tabindex': 'someFormlyExpression' // http://docs.angular-formly.com/docs/formly-expressions
}
Good luck!

Unable to change view when scope gets changed in ui-select angularjs

<ui-select multiple ng-model="content.categories" theme="bootstrap"name="category" on-select="isCategorySelected()" >
<ui-select-match placeholder="Select Category">
{{ $item.label }}
</ui-select-match>
<ui-select-choices repeat="category.value as category in categories | filter: {label: $select.search}">
<div ng-bind-html="category.label | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
The shown is my html code
$scope.categories = [
{ label: 'Action', value: 'action' },
{ label: 'Adventure', value: 'adventure' },
{ label: 'Comedy', value: 'comedy' },
{ label: 'Crime', value: 'crime' },
{ label: 'Faction', value: 'faction' },
{ label: 'Fantasy', value: 'fantasy' },
{ label: 'Historical', value: 'historical' },
{ label: 'Horror', value: 'horror' },
{ label: 'Mystery', value: 'mystery' },
{ label: 'Paranoid', value: 'paranoid' },
{ label: 'Philosophical', value: 'philosophical' },
{ label: 'Political', value: 'political' },
{ label: 'Realistic', value: 'realistic' },
{ label: 'Romance', value: 'romance' },
{ label: 'Saga', value: 'saga' },
{ label: 'Satire', value: 'satire' },
{ label: 'Science fiction', value: 'sciencefiction' },
{ label: 'Slice of Life', value: 'sliceoflife' },
{ label: 'Speculative', value: 'speculative' },
{ label: 'Thriller', value: 'thriller' },
{ label: 'Urban', value: 'urban' }
];
This is my javascript code.
The above code works fine for selecting the defind items in the categories.
Now if I assign a value to ng-model of ui-select it isn't updatind the view as we select an item.
$scope.content.categories = [action];
the above code snippet should change the view,but its not.Please help me how to do this.
You should be getting action is not defined in the console. Just put quotes around it.
$scope.content.categories = ['action'];
var app = angular.module('app', ['ui.select', 'ngSanitize']);
app.controller('myController', function($scope) {
$scope.content = {};
$scope.content.categories = ['action'];
$scope.setAdventure = function() {
$scope.content.categories = ['adventure'];
};
$scope.pushComedy = function() {
if ($scope.content.categories.indexOf('comedy') === -1) {
$scope.content.categories.push('comedy');
}
};
$scope.categories = [{
label: 'Action',
value: 'action'
}, {
label: 'Adventure',
value: 'adventure'
}, {
label: 'Comedy',
value: 'comedy'
}, {
label: 'Crime',
value: 'crime'
}, {
label: 'Faction',
value: 'faction'
}, {
label: 'Fantasy',
value: 'fantasy'
}, {
label: 'Historical',
value: 'historical'
}, {
label: 'Horror',
value: 'horror'
}, {
label: 'Mystery',
value: 'mystery'
}, {
label: 'Paranoid',
value: 'paranoid'
}, {
label: 'Philosophical',
value: 'philosophical'
}, {
label: 'Political',
value: 'political'
}, {
label: 'Realistic',
value: 'realistic'
}, {
label: 'Romance',
value: 'romance'
}, {
label: 'Saga',
value: 'saga'
}, {
label: 'Satire',
value: 'satire'
}, {
label: 'Science fiction',
value: 'sciencefiction'
}, {
label: 'Slice of Life',
value: 'sliceoflife'
}, {
label: 'Speculative',
value: 'speculative'
}, {
label: 'Thriller',
value: 'thriller'
}, {
label: 'Urban',
value: 'urban'
}];
});
body {
padding: 15px;
}
.select2 > .select2-choice.ui-select-match {
/* Because of the inclusion of Bootstrap */
height: 29px;
}
.selectize-control > .selectize-dropdown {
top: 36px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-sanitize.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-select/0.12.0/select.js"></script>
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-select/0.12.0/select.min.css">
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.8.5/css/selectize.default.css">
<div ng-app='app' ng-controller='myController'>
<button ng-click="setAdventure()">setAdventure</button>
<button ng-click="pushComedy()">pushComedy</button>
{{ content.categories }}
<ui-select multiple ng-model="content.categories" theme="bootstrap" name="category" on-select="isCategorySelected()" style="width: 300px;">
<ui-select-match placeholder="Select Category">
{{ $item.label }}
</ui-select-match>
<ui-select-choices repeat="category.value as category in categories | filter: {label: $select.search}">
<div ng-bind-html="category.label | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
</div>

How to remove treeview child node using jquery

I have a treeview like below, i need to remove one child from the list based on the user. Can any one tell me how to remove the child from the treeview.
var treedata = [
{
label: 'Floor', type: 'Country',
children: [
{
label: 'Bangalore', type: 'Location',
children: [{ label: 'Technopolis', type: 'facility', id: 1 }, { label: 'Ecity Tower-2', type: 'facility', id: 2 }, { label: 'Bagmane', type: 'facility', id: 3 }, { label: 'Cyber Park', type: 'facility', id: 4 }]
},
{
label: 'Hyderabad', type: 'Location',
children: [{ label: 'Hitech City ', type: 'facility', id: 5 }, { label: 'Cyber City', type: 'facility', id: 6 }]
},
{
label: 'Chennai', type: 'Location',
children: [{ label: 'XXX', type: 'facility', id: 7 }]
},
{
label: 'Mumbai', type: 'facility', id: 8
}
]
},
{
label: 'Role Administration', type: 'Role',
children: [{ label: 'Assign Role', type: 'Role', id: 1 }]
},
{
label: 'Hoteling Admin', type: 'Hoteling',
children: [{ label: 'Hoteling', type: 'Hoteling', id: 1 }]
}
];
The above is my jquery tree data. I want to remove the role administration if the user is a normal user by checking the user role.
Anyone help me how to do using jquery.
Thanks
You can use $.grep() to filter the array to a new array based on whatever conditions you want.
var userRole='normal';
if( userRole === 'normal'){
treeview = $.grep(treeview, function(item){
return item.label != 'Role Administration';
});
}
grep() API docs

How to disable a particular row in Picker in Sencha touch

I have created a picker in Sencha touch 2.1. My Data is displaying properly. I want to disable a particular value not all so that if I select that value and click "doneButton" then it shouldn't be taken.
Example:
function loadPicker(paramName, valueSet) {
Ext.Viewport.remove(Ext.getCmp(paramName + 'Pickerfield'), true);
if (!paramName.picker) {
paramName.picker = Ext.Viewport.add({
xtype: 'picker',
id: paramName + 'Pickerfield',
useTitles: true,
slots: [{
name: paramName,
title: paramName,
data: valueSet
}],
doneButton: {
listeners: {
tap: function(button, event, eOpts) {
var selectedPacingModeValue =
Ext.getCmp(paramName + 'Pickerfield').getValue()[paramName];
sendSetPendingRequest(paramName, selectedPacingModeValue);
}
}
}
});
}
}
lets take these are the values in my picker field. What I am doing on select of an value and click of "doneButton", I am showing the value in a textfield. What I want is if I will select "option 2" and click "doneButton" then option 2 shouldn't be displayed in textfield but for all other values this selecting and showing in textfield operation should work.
You can just get the selected record and check that flag upon click of the done button, then move to textbox (or not).
Ext.create('Ext.form.Panel', {
fullscreen: true,
items: [
{
xtype: 'fieldset',
title: 'Select',
items: [
{
xtype: 'selectfield',
itemId: 'mySelectField',
label: 'Choose one',
options: [
{
text: 'apple',
value: 50
}, {
text: 'orange',
value: 100,
disabled: true
}, {
text: 'banana',
value: 200
}, {
text: 'papaya',
value: 300
}
]
},
{
xtype: 'button',
text: 'done',
handler: function(button){
var panel = button.up(),
sf = panel.down('#mySelectField'),
tf = panel.down('#answerfield');
/* you can only access the raw value unless you use
* an actual store and an actual model with the
* disabled field. In that case you can do
* sf.getRecord().get('disabled')
*/
if(sf.getRecord().raw.disabled === true){
tf.setValue(''); //noting to see :)
} else {
tf.setValue(sf.getRecord().get('text')); //display value
}
}
},
{
xtype: 'textfield',
itemId: 'answerfield',
title: 'answer'
}
]
}
]
});
Working fiddle: http://www.senchafiddle.com/#d46XZ
UPDATE
Like you asked: with the picker
Ext.Loader.setConfig({
enabled: true
});
Ext.application({
name: 'SenchaFiddle',
launch: function() {
var picker = Ext.create('Ext.Picker', {
slots: [
{
name : 'stuff',
title: 'Stuff',
data : [
{
text: 'apple',
value: 50
}, {
text: 'orange',
value: 100,
disabled: true
}, {
text: 'banana',
value: 200
}, {
text: 'papaya',
value: 300
}
]
}
],
listeners: {
change: function(p, value){
var tf = panel.down('#answerfield'),
firstSlot = p.getItems().get(1), //index 0 is the toolbar 1 first slot and so on..
selectedRecord = firstSlot.getData()[firstSlot.selectedIndex];
if(selectedRecord.disabled === true){
tf.setValue(''); //noting to see :)
} else {
console.log(selectedRecord);
tf.setValue(selectedRecord.text); //display value
}
}
}
});
var panel = Ext.create('Ext.form.Panel', {
fullscreen: true,
items: [
{
xtype: 'fieldset',
title: 'Select',
items: [
{
xtype: 'button',
text: 'show picker',
handler: function(button){
Ext.Viewport.add(picker);
picker.show();
}
},
{
xtype: 'textfield',
itemId: 'answerfield',
title: 'answer'
}
]
}
]
});
}
});
working fiddle: http://www.senchafiddle.com/#SFgpV

Categories

Resources