Using Factory to Display Navigation for Application? - angularjs

I am still learning so any advice or improvements would be appreciated! I am looking to build a Navigation for my Angular App using the Service i built if its usable.
Quick Summary of Functionality:
User MouseOver Parent Item
Submenu Items Display under Active Parent Item
Here is what i have so far for my Service Structure:
app.factory("NavigationService", function () {
var e = [{
title: "Parent1",
type: "parentitem",
children: [{
title: "SubofParent",
type: "subitem",
href: "/location"
}]
}, {
title: "Parent2",
type: "parentitem",
children: [{
title: "SubofParent",
type: "subitem",
href: "/location"
}]
}, {
title: "Parent3",
type: "parentitem",
children: [{
title: "SubofParent",
type: "subitem",
href: "/location"
}]
}
}];
});
As you can see its a very simple structure but what i would like to know is how i can use this structure to ng-repeat the Parent Items and then display the SubItems on Hover over specific parent item, if that makes sense?
I am unsure how to build the controller to handle this method.
Any Advice on how to achieve this would be great.

<li ng-repeat="item in data" >
<ul ng-mouseover="isChildrenVisible=true" ng-mouseleave= "isChildrenVisible=false"> {{item.title}}</ul> //parent element
<ul ng-show="isChildrenVisible">
<li ng-repeat="child in item.children "> //child element
<p>{{child.title}}</p>
</li>
</ul>
</li>
Here I make child element hidden by default (initialize isChildrenVisible varible to false). when user mouse over the parent element then I will make isChildrenVisible=true and on mouse leave i make this varible false.

Related

In angular formly, how to add ng-click or ng-change to a checkbox?

I am using angular-formly, I am trying to add the normal angular events to a checkbox but no joy. Here is what I have:
{
type: "checkbox",
key: "is_active",
templateOptions: {
type: "",
label: "Is Active"
}
}
I looked over the documentations over and over and I can not find the solution. Please show where to add ng-click or ng-change in the above.
I hoped something like the below would work:
{
type: "checkbox",
key: "is_active",
templateOptions: {
type: "",
label: "Is Active"
},
ngClick : "functionName"
}
where functionName is a function inside the controller that renders the form. So my functions will always be in my controller, I just need to define or pass the event to the checkbox
It's been awhile since I've messed with formly but I believe this should do
{
type: "checkbox",
key: "is_active",
templateOptions: {
type: "",
label: "Is Active",
onClick: yourControllerFunctionHere //notice this isn't a string but a reference to your controller function
}
}
This is referenced in the ngModelAttrsTemplateManipulator documentation. I love formly but the documentation is hard to navigate
use ngModelElAttrs attribute:
{
type: "checkbox",
key: "is_active",
templateOptions: {
label: "Is Active"
},
ngModelElAttrs: {
'ng-change': "model.text = 'asdf'"
}
}
in this fiddle (http://jsbin.com/xavitufudu/1/edit?js,output) I added your checkbox as a first field, which on change changes next field's content.
this approach does not have direct access to outer scope, but rather to formly's scope. In order to reach an outer scope we can add field's controller, which may access outer scope (variable functions):
{
type: "checkbox",
key: "is_active",
templateOptions: {
label: "Is Active"
},
ngModelElAttrs: {
'ng-change': "myFunc()"
},
controller: function ($scope) {
$scope.myFunc = function () {
vm.model.text = 'Another text';
};
}
}
here, we access vm.model.text via outer scope (although we could also access it via inner field's scope as $scope.model.text)

angular js ng-class shows expression as class instead of processing it

I'm trying to make highlighted menu items by using angular js. I've read this question and tried implementing the anwser, but instead of angular evaluating the expression, it just shows it as the class name. I don't know what's going on.
I have the menu items listed as JSON, and the iterate trough it with ng-repeat. Once the list items are created, I want the angular to add a class of 'active', if the location url is the same as the link.href attribute of a menu item (it's a json attribute, not the html one).
Here's the relevant html:
<div class="header" ng-controller="NavbarController">
<ul>
<li ng-repeat="link in menu" ng-class="{ active: isActive({{ link.href }}) }"><a ng-href="{{ link.href }}">{{ link.item }}</a>
</li>
</ul>
</div>
and my controller:
.controller('NavbarController', function ($scope, $location) {
// navbar links
$scope.menu = [
{
item: 'PTC-Testers',
href: '#/PTC-Testers'
},
{
item: 'articles',
href: '#/articles'
},
{
item: 'PTC sites',
href: '#/sites'
},
{
item: 'account reviews',
href: '#/account_reviews'
},
{
item: 'forum',
href: '#/forum'
},
{
item: 'contact us',
href: '#/contact'
},
{
item: 'login',
href: '#/login'
}
]; // end $scope.menu
$scope.isActive = function (viewLocation) {
return viewLocation === $location.path();
};
});
This is the navbar part of a bigger project, and I tried only inserting the relevant code. If you need further info to understand the question properly, please let me know.
It should be ng-class="{'active' : isActive(link.href)}"
You didn't end the curly brace in ng-class and its better to put class name inside quotes

two-way binding in directive, model from service non-assignable

I am getting the following error: "Expression '{0}' used with directive '{1}' is non-assignable!", as can be shown here: https://docs.angularjs.org/error/$compile/nonassign
Edit: Having moved the config object into the scope this part is resolved, however the models are still not bound as expected. http://plnkr.co/edit/AVs2IW75oWavpsPNDgnb?p=preview
Old plunker: http://plnkr.co/edit/AVs2IW75oWavpsPNDgnb?p=preview
(Try and edit a field and check the console)
I don't really understand the problem which is why that link can't help me to solve it. I am using a directive to bind data, and the data that is being "bound" is actually pointing to a service.
<multi-edit model="profileService.current" config="{
title: 'Edit profile description',
fields: [
{name: 'Title', model: profileService.current.title, input: true},
{name: 'Description', model: profileService.current.description, textarea: true}
]}">
CLick me
</multi-edit>
So I am trying to edit profileService.current.title for example, by using the ng-model config.fields[0].model. It can read the data correctly, but not write to it. What do I need to do in order to be able to write to the correct models?
UPDATED
You should use a scope model for "config".
Put this in your main controller:
$scope.config = {
title: 'Edit profile description',
fields: [{
name: 'Title',
model: 'title',
input: true
}, {
name: 'Description',
model: 'description',
textarea: true
}]
};
and then in your main HTML:
<multi-edit model="profileService.current" config="config">
CLick me
</multi-edit>
Then, in your directive HTML:
<li ng-repeat="(key, value) in config.fields">
<input ng-if="value.input" type="text" ng-model="model[config.fields[key].model]" />
<textarea ng-if="value.textarea" type="text" ng-model="model[config.fields[key].model]"></textarea>
</li>
See the updated plunker.

Ionic angular js

Hello guys im struggeling with ionic and angular i build an news site view with menu points like this
ionic menu points
i wrote my news in an array
for example
http://plnkr.co/edit/ZWOHlCmZDxUkd4laWN4t?p=catalogue
.controller('NewsCtrl', function($scope) {
var items = [
{id: 1, news_item: 'NEWS EXAMPLE'}
];
});
how can i route the right path to the news_item.html site which i klicked on. so if i click on first one i get the tempalte with 'NEWS EXAMPLE'
I couldn't test my answer because your plunker is not working. I think you forgot the index.html file.
But I believe you should add to your items list the url to redirect your page :
.controller('NewsCtrl', function($scope) {
var items = [
{id: 1, news_item: 'NEWS EXAMPLE', template_url : '/path/to/template'}
];
});
Then you can add the path to a href in your <a></a> block.
Hope it will help
Change your variable to be $scope.links this will make it available in the view for repeating using ng-repeat. You can then access values in the JSON Object as setting your href value to the template_url.
.controller('NewsCtrl',function($scope)({
$scope.links = [{
id:1,
news_item: 'NEWS EXAMPLE',
template_url: '/path/to/template'
},
{
id:2,
news_item: 'NEWS EXAMPLE',
template_url: 'path/to/tempalte'
}];
})
<div class='rows' ng-repeat="link in links">
<a href='{{link.template_url}}' class='col' value='{{link.news_item}}' />
</div>
Hope this helps

Sencha Touch Navigation View - Changing Title does not work on Back Button

I have a Tab Panel as my initial item inside a Navigation View. When I change tab, I'm updating the Title in the Navigation Bar via:
activeitemchange: function(container){
var navigationView = container.up('navigationview'),
navigationBar = navigationView.getNavigationBar(),
newTabTitle = value.tab._title;
navigationBar.setTitle(newTabTitle);
}
The problem is that when I push a new view onto the Navigation View, the Text for the Back Button uses the old/original Title, and not the updated Title. Clicking the Back Button also sets the Navigation View Title to the old/original Title.
The closest I got to finding a solution was this:
http://www.sencha.com/forum/showthread.php?189284-Navigation-View-Title-(IPad-App)
But I get an 'undefined' error on the navigationBar.refreshProxy() call, so I'm assuming that only works for an older version of ST.
Any help would be great,
Thanks.
I don't know if you found any answer for this question or solved it by your own since question is quite old. But I tried what you wanted to do and I managed to get the result successfully. So here's the code. I'm following MVC strictly so posting necessary files that need this to work. Basically, views and controllers.
Main.js containing TabPanel
Ext.define('SO.view.Main', {
extend: 'Ext.tab.Panel',
xtype: 'main',
requires: [
'Ext.TitleBar',
'Ext.Video'
],
config: {
tabBarPosition: 'bottom',
items: [
{
title: 'Welcome',
iconCls: 'home',
styleHtmlContent: true,
scrollable: true,
html: [
"You've just generated a new Sencha Touch 2 project. What you're looking at right now is the ",
].join("")
},
{
title: 'Get Started',
iconCls: 'action',
items: [
{
xtype: 'button',
text: 'Push a new view!',
action:'push_new_view'
}
]
}
]
}
});
Nav.js having navigation view and default item as above tab panel
Ext.define('SO.view.Nav', {
extend: 'Ext.NavigationView',
xtype: 'nav',
config:{
fullscreen: true,
items: [
{
title: 'Default View',
xtype:'main'
}
]
}
});
And finally, controller. I did every user interaction handling in controller itself.
Ext.define('SO.controller.Nav',{
extend:'Ext.app.Controller',
config:{
refs:{
views:['SO.view.Main','SO.view.Nav'],
navView:'nav',
tabView:'main'
},
control:{
tabView:{
activeitemchange:'changeTitle'
},
'button[action=push_new_view]':{
tap:'pushNewView'
}
}
},
changeTitle:function(container,value,oldValue,eOpts ){
console.log(value.title);
this.getNavView().getNavigationBar().setTitle(value.title);
},
pushNewView:function(){
var activeTabTitle = this.getTabView().getActiveItem().title;
var controller = this;
controller.getNavView().push({
title: 'Second',
html: 'Second view!'
});
controller.getNavView().getNavigationBar().getBackButton().setText(activeTabTitle);
controller.getNavView().getNavigationBar().getBackButton().on('tap',function(self){
controller.getNavView().getNavigationBar().setTitle(activeTabTitle);
});
}
}
);
As you can see, I've attached function that changes title according to selected tab in changeTitle function.
the function pushNewView pushes new view and let's you ovverride back button behavior on tap. What I did is simply, get activeItem() from tab panel which holds a button that pushes new view. Once we got activeItem we can get it's title and that title need to be set to backButtnoText. So I traverse navigation view and getBackButton instance and simply by calling setText() method changed back button text.
Same time, I've attached event handler to back button, as we do want to change navigation bar title to previous title. So once, use taps back button, we set back the title to title we got in above step. You might want to detach event handler once you're done with eveything as it might cause problems or I'd rather say it'd be good.
Just try this, it just works.
You will need to change the title of the parent viewport, not just to the navigation view tile. Basically the Navigation title is already changing by itself based on the parent view title, and all pushed component title.
var view = Ext.create('Ext.NavigationView', {
fullscreen: true,
items: [{
title: 'Change this title ',
items: [{
xtype: 'button',
text: 'Push a new view!',
handler: function() {
view.push({
title: 'Second Title',
html: 'Second view!'
});
}
}]
}]
});
It should look something like this:
activeitemchange: function(container){
var newTabTitle = value.tab._title;
container.setTitle(newTabTitle);
}
//viewAppt is the reference of the view
//Use this
viewAppts.query('#headerTitlebar')[0].setTitle('Title');
// Instead of this
this.getApptsHeaderTitlebar().setTitle('Title');

Resources