angularJS add a class + set default for bootstrap Tabs - html

I have an angular tabbable here. How can I set default tab? + add a class to specific tab?
http://plnkr.co/edit/FPMf8i
e.g. I want the tab 2 to be slected by default. Then tab 1 have a specific class.
I tried
element.children[1].addClass('test');
element[0].children[0].addClass('test');
element[0].addClass('test');
but keep getting an error
Can't use jquery has to be library already there.

Add an initial value for your ng-model, then use ng-class to set dynamic classes
Plnkr
http://plnkr.co/edit/udxAT0?p=preview
View
<div ng-controller="TabsCtrl">
<div class="tabbable" ng-model="currentTab">
<div class="tab-pane" ng-class="{'special-class': currentTab == 1}" title="1" value="1">
Content 1
</div>
<div class="tab-pane" title="2" value="2">
Content 2
</div>
</div>
</div>
Controller
var app = angular.module('plunker', ['bootstrap']);
app.controller("TabsCtrl", function($scope) {
$scope.currentTab = 1;
});

Related

Framework7 formToData not working

I have a screen login in my aplication and to get the form data in framework i need to use formtoData but it wasnt working, so i decided to create another project and copy paste framework docs script but still isnt working.
Index.html(the test project)
<div class="pages navbar-through toolbar-through">
<!-- Page, "data-page" contains page name -->
<div data-page="index" class="page">
<!-- Scrollable page content -->
<div class="page-content">
<form id="my-form" class="list-block">
<ul>
<li>
<div class="item-content">
<div class="item-inner">
<div class="item-title label">Name</div>
<div class="item-input">
<input type="text" name="name" placeholder="Your name">
</div>
</div>
</div>
</li>
</ul>
</form>
<div class="content-block">
Get Form Data
</div>
</div>
</div>
</div>
js (test project)
// Initialize app
var myApp = new Framework7();
// If we need to use custom DOM library, let's save it to $$ variable:
var $$ = Dom7;
$$('.form-to-data').on('click', function(){
alert("dwdq");
var formData = myApp.formToData('#my-form');
alert(formData);
});
Does anyone know why is it not working? thx in advance.
They changed the function, instead of formToData now is formToJSON
You can use booth:
formtoData or formToJson will return the same value: [object Object]
Just use JSON.stringify() to get the desired result.
$$('.form-to-data').on('click', function(){
var formData = myApp.formToData('#my-form');
var formJSON = myApp.formToJSON("#my-form");
console.log(JSON.stringify(formData));
console.log(JSON.stringify(formJSON));
});
{"name":"Alexandre"}
{"name":"Alexandre"}
Or you can even serialize the form like that:
$$('.form-to-data').on('click', function(){
var formData = $$.serializeObject(myApp.formToJSON($$("#my-form")));
console.log(formData);
});
name=Alexandre
Edit: Framework7 got updated to v4, and now it works this way:
Single Line:
var dados = JSON.stringify(myApp.form.convertToData('#my-form'));
They changed the function again, at least in V2. The new function that works for me is:
var formData = myApp.form.convertToData("#form-id");
var formString = JSON.stringify(formData);
Framework 7 convertToData is ignoring input type text array: for example:
<input type="text" name="no_invoice[]" />
Removing [] doesn't work either.
F7 only take as array checkbox/radio fields, this bug must be solved.
I solved using javascript:
new FormData(your_form);

How to show/hide in Angular2

I have a component that show/hide element by clicking a button.
This is my html
<div *ngFor="let history of histories | sortdate: '-dateModified'">
<p><b>{{ history.remarks }}</b> - <i>{{history.dateModified | date:'short'}}</i></p>
<a href="google.com"
[class.datatable-icon-right]="history.$$expanded"
[class.datatable-icon-down]="!history.$$expanded"
title="Expand/Collapse Row"
(click)="toggleExpandRow(history)"></a>
<!-- hide/show this by clicking the button above.-->
<div *ngFor="let step of history.steps; let i = index">
<b>{{i+1}}.</b> {{step}}
<span class="clear"></span>
</div>
<hr />
</div>
and my .ts
toggleExpandRow(row) {
console.log('Toggled Expand Row!', row);
//row
return false;
}
trying to search but, can't find any same sample.
On jquery, I can do this, but on Angular2, I am having hard time to figure this.
There are two options:
1- You can use the hidden directive to show or hide any element
<div [hidden]="!edited" class="alert alert-success box-msg" role="alert">
<strong>List Saved!</strong> Your changes has been saved.
</div>
2- You can use the ngIf control directive to add or remove the element. This is different of the hidden directive because it does not show / hide the element, but it add / remove from the DOM. You can loose unsaved data of the element. It can be the better choice for an edit component that is cancelled.
<div *ngIf="edited" class="alert alert-success box-msg" role="alert">
<strong>List Saved!</strong> Your changes has been saved.
</div>
Use the ngIf in your repeated rows. Create a boolean property called showStep to indicate whether the row should be expanded or not.
<div *ngFor="let step of history.steps; let i = index" ngIf="history.showStep">
<b>{{i+1}}.</b> {{step}}
<span class="clear"></span>
</div>
Then, in your .ts file:
toggleExpandRow(history) {
history.showStep = !history.showStep
//note the same porperty of showStep that is used in your html
}
Extra:
In fact, to save a few lines of codes, you don't even need the toggleExpandRow function at all. You can do it inline in your html:
//other attributes omitted for brevity
<a (click)="history.showStep = !history.showStep">

Ng-show will not update when ng-click is inside div

I have a DIV with ng-show.
When I run ng-click on an element outside of the DIV, it works fine and I can hide it.
When I run ng-click on an element inside of the DIV, it does not work. I can see the variable beeing changed when i console.log it, but the view will not update.
I have tried to use $scope.$apply() but it gets an error and says it is already running $apply().
Parts of controller:
$scope.selectedActivity = {
"dayNr": 0,
"actNr": 0
};
$scope.resetSelectedActivity = function () {
console.log("SelAct: ", $scope.selectedActivity);
$scope.selectedActivity.dayNr = -1;
$scope.selectedActivity.actNr = -1;
console.log("SelAct: ", $scope.selectedActivity);
};
$scope.setSelectedActivity = function (dayNr, actNr) {
console.log("SelAct: ", $scope.selectedActivity);
$scope.selectedActivity.dayNr = dayNr;
$scope.selectedActivity.actNr = actNr;
console.log("SelAct: ", $scope.selectedActivity);
};
Parts of HTML:
<div ng-repeat="x in xs">
<ion-scroll>
<div ng-repeat="y in ys track by $index">
<div ng-click="setSelectedActivity($parent.$index, $index)">
<!--THE PROBLEM IS HERE-->
<div ng-show="selectedActivity.dayNr == $parent.$index && selectedActivity.actNr == $index">
<div>
<!--THIS LOGS OUT CORRECT VALUES BUT NG-SHOW IS NOT UPDATED-->
<div ng-click="resetSelectedActivity()">
Reset
</div>
</div>
</div>
<div>
<img src="img/checkButtonOverlay.png" />
</div>
</div>
<!--THIS LOGS OUT CORRECT VALUES AND NG-SHOW _IS_ UPDATED-->
<button ng-click="resetSelectedActivity()">reset</button>
</div>
</ion-scroll>
</div>
Please note that i have removed A LOT from the code because of confidentiality, but the principle should be the same.
Thank you!
Found the problem!
I had a ng-click that showed the DIV outside. When I clicked both ng-clicks got entered.
So First resetSelectedActivity() and then it got set again in setSelectedActivity().
Fixed it using:
<div ng-click="resetSelectedActivity($parent.$index, $index, $event)">
...
</div>
and:
$scope.setSelectedActivity = function (dayNr, actNr, event) {
$scope.selectedActivity.dayNr = dayNr;
$scope.selectedActivity.actNr = actNr;
//This cancel the mouseclick
event.stopPropagation();
};

ng-if and ng-show in my Ionic application, neither works

The html code goes something like this:
<div ng-if="name=='John'">
<div class="item item-avatar"> <img ng-src="john.jpg"></div>
</div>
<div ng-if="name=='Margaret'"
<div class="item item-avatar"> <img ng-src="margaret.jpg"></div>
</div>
Instead of ng-if, I've tried using ng-show as well. Neither worked. Both John as well as Margaret showed on the page no matter which I used. I tried with ng-switch also.
The variable 'name' I initialized earlier on the same HTML file as:
<a class="item item-avatar item-icon-right" ng-init="name = 'John'" href = "#/Page3"></a>
Clicking on the above line leads to Page3 where I need to display either John or Margaret depending on the value of 'name'.
Is the syntax wrong or something, because that could be very well possible. I'm new to Ionic and AngularJS.
Try this:
<div ng-show="name=='John'" ng-init="name = 'John'">
<div class="item item-avatar"> John</div>
</div>
<div ng-show="name=='Margaret'"
<div class="item item-avatar"> Margaret</div>
</div>
Works for me. I just change ng-if to ng-show - which will shows div content when true and hide it otherwise. I also use ng-init inside a div.
Are you sure you started Angular? Did you set the ng-app directive?
It would help if you could provide a working example if you have other problems.
angular.module('app', []);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-init="name = 'John'">
<button type="button" ng-click="name='John'">John</button>
<button type="button" ng-click="name='Margaret'">Margaret</button>
<div ng-if="name=='John'">
This is John
</div>
<div ng-if="name=='Margaret'">
This is Margaret
</div>
</div>
I fixed you plunker - now it should be working.
Bug #1: ng-init is for initialization not to set values at runtime -> use ng-click instead
Bug #2: You use the same controller for all pages but for each page a new controller will be initialized, which resets the 'name' property
I implemented a setName function to set the name in the rootscope and to go to page3. In a correct implementation you should pass the name as a $stateparam to the new state/page. But for that please have a look at the ui-router documentation.
$scope.setName = function(name) {
console.log(name);
$rootScope.name = name;
$state.go('Page3');
};

Dojo StackController: how can I set a title for each button?

(using dojo 1.10.1)
I am working with dojo's dijit/layout/StackContainer and dijit/layout/StackController which are working fine, here is a simplified example. My problem is that I cant find a "clean" way to add mouseover titles to each controller button that the StackController creates?
html
<div>
<div data-dojo-type="dijit/layout/StackContainer"
data-dojo-props="id: 'contentStack'">
<div data-dojo-type="dijit/layout/ContentPane" title="one">
<h4>Group 1 Content</h4>
</div>
<div data-dojo-type="dijit/layout/ContentPane" title="two">
<h4>Group 2 Content</h4>
</div>
<div data-dojo-type="dijit/layout/ContentPane" title="three">
<h4>Group 3 Content</h4>
</div>
</div>
<div data-dojo-type="dijit/layout/StackController" data-dojo-props="containerId:'contentStack'"></div>
</div>
So for each title in each child contained within the StackContainer, a button is cerated by the StackController with the same label, but the button has no mouseover text, I need to add that as well.
I am not interested in any solution that involves me looping over the nodes and finding each button, its just not nice.
One of the best solutions would be to send properties, methods and events of buttons via corresponding ContentPanes. For example:
<div data-dojo-type="dijit/layout/ContentPane" title="one" data-dojo-props=
"controllerProps: {onMouseOver: function(){"doSomething"}}">
<h4>Group 1 Content</h4>
</div>
But as far as I understood this is not possible, because StackController passes to its buttons "title" and some other unimportant properties of ContentPane. So if you are really interested in above solutions you have to override the default behavior of StackController. Which is possible, but needs more time! :)
So I suggest you other solution which works and faster. You give to StackController-div an id:
<div id="myController" data-dojo-type="dijit/layout/StackController" data-dojo-
props="containerId:'contentStack'"></div>
You use "dijit/registry" to call that id:
var controllerWidget = registry.byId("myController");
You have now StackController widget. Call getChildren() method of it and you have an array of Button widgets. The rest I guess straightforward.
Here is the JSFiddle example.
Cheers!
Update:
Hey I have found another solution, which satisfies your requirements: "No button search"
These are the properties which StackController passes to buttonWidget:
var Cls = lang.isString(this.buttonWidget) ? lang.getObject(this.buttonWidget) : this.buttonWidget;
var button = new Cls({
id: this.id + "_" + page.id,
name: this.id + "_" + page.id, // note: must match id used in pane2button()
label: page.title,
disabled: page.disabled,
ownerDocument: this.ownerDocument,
dir: page.dir,
lang: page.lang,
textDir: page.textDir || this.textDir,
showLabel: page.showTitle,
iconClass: page.iconClass,
closeButton: page.closable,
title: page.tooltip,
page: page
});
So if you give a tag "tooltip" for your ContentPane, it will appear in buttonWidget as "title".
<div data-dojo-type="dijit/layout/ContentPane" title="one" tooltip="First Page">
Here is another JSFiddle example.