AngularJS ng-include is not working in UI Bootstrap - angular-ui-bootstrap

I am very new to AngularJS. I have read several posts on this topic, but am still unable to get data loaded via ng-include
Here is my html and js code
js
.controller('TabsDemoCtrl', function ($scope, $window) {
$scope.tabs = [
{
title:'Home',
content:"test.html"
},
{
title:'Profile',
content:"test.html"
},
{
title:'Messages',
content:"test.html"
},
{
title:'Settings',
content:"test.html"
}
];
})
html
<div class="card-body card-padding" data-ng-controller="TabsDemoCtrl">
<tabset vertical="true">
<tab ng-repeat="tab in tabs" heading="{{tab.title}}" active="tab.active" disable="tab.disabled">
<div ng-include="tab.content"></div>
</tab>
</tabset>
</div>
test.html
<h1>This is html file</h1>
I don't know what is the issue and why test.html is not being loaded. Can anyone please help me to find out the issue?

Related

Use Stimulus Controller in multiple places

I want to be able to use a Stimulus Controller in multiple places in a web app. I want do something like this:
<div data-controller="mycontroller">
<OneComponent />
</div>
<SomeOtherComponent />
<div data-controller="mycontroller">
<NewComponent />
</div>
But the controller just seem to connect to the first Component and not in the second. Is it possible to use it as I'm intending to?
Thanks!
Stimulus controllers can be reused. See this sample.
Possible problems that may prevent this from working is if there is a JS error, or that you expect elements in nested components to be used in the parent component, if they have not been rendered yet.
const application = Stimulus.Application.start()
application.register("hello", class extends Stimulus.Controller {
connect() {
console.log("connect to", this.element.getAttribute("data-language"))
}
static get targets() {
return [ "name" ]
}
greet() {
if (this.element.getAttribute("data-language") == "es-ES") {
console.log(`¡Hola, ${this.nameTarget.value}!`);
} else {
console.log(`Hello, ${this.nameTarget.value}!`);
}
}
})
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script src="https://unpkg.com/stimulus/dist/stimulus.umd.js"></script>
</head>
<body>
<div data-controller="hello" data-language="en-US">
<input data-hello-target="name" type="text" value="John">
<button data-action="click->hello#greet">Greet</button>
</div>
<div data-controller="hello" data-language="es-ES">
<input data-hello-target="name" type="text" value="Jose">
<button data-action="click->hello#greet">Saudar</button>
</div>
</body>
</html>

How to run Angular JS on after page load rendered html?

I'm developing asp.net mvc a project with angular js.
I'm working on tabs and install related partial view after click event.
I am sending with partial view html of the json to main page but angular codes doesn't work on the page
What can i do?
Sample Problem
html:
<div ng-app="MyAppS">
<div ng-controller="AnaTest">
<button id="btn1" ng-click="btn1Click()">click</button>
</div>
<div id="m_area">
</div>
<br />{{ 'Hello Angular' }}</div>
javascript:
var m_app = angular.module('MyAppS', []);
function AnaTest($scope) {
$scope.btn1Click = function () {
var runtimeBtn = angular.element("<button ng-click=\"btn2Click()\">Help Me! </button>");
$('#m_area').html(runtimeBtn);
};
$scope.btn2Click = function(){
debugger;
alert('Why can not show?!');
};
};
m_app.controller('AnaTest', AnaTest);
You need to $compile it:
var runtimeBtn = $compile(angular.element("<button ng-click=\"btn2Click()\">Help Me!</button>"))($scope);
See it here: http://jsfiddle.net/7yqrjdkk/8/
However, a more "Angular" way to do it would be putting it under the same controller/scope and simply using ng-show, like this: http://jsfiddle.net/7yqrjdkk/9/

Multiple selection in angular bootstrap typeahead

Is it possible to select multiple values from angular ui bootstrap typeahead?
http://angular-ui.github.io/bootstrap/#/typeahead
Hi without changing the codebase probably not - you could try https://github.com/rayshan/ui-multiselect
I recently had the same requirement and was able to solve it by overriding the internal bootstrap implementation via an alternate popup-template. I created a new directive (multi-select-typeahead) to encapsulate the change.
The template uses an ng-init to pass the scope reference (of the typeahead popup directive) to the multi-select-typeahead directive. There the directive overrides the parent's scope. $scope.$parent in this case is the bootstrap typeahead directive itself. The custom directive provides a new implementation of select() which is called internally by angular bootstrap. The new implementation prevents the popup from closing and removes selected items from the list.
The alternate popup I provided is almost entirely the same as the default angular bootstrap typeahead template "uib/template/typeahead/typeahead-popup.html". The only modification was the addition of the ng-init which passes its scope to the multi-select-typeahead directive.
I'm sure if you are clever enough you could render the angular bootstrap default template by reference and inject the ng-init part, removing the duplicated bootstrap code. This would make the solution a bit more resilient to future angular bootstrap changes. That being said, the solution is already quite a hack and is prone to breaking in future major releases.
Hope this is useful to someone!
angular.module('typeahead.demo', [
'ngAnimate',
'ngSanitize',
'ui.bootstrap'
]);
angular
.module('typeahead.demo')
.controller('TypeaheadDemo', TypeaheadDemo);
function TypeaheadDemo($scope) {
$scope.addItem = addItem;
$scope.itemApi = itemApi;
$scope.items = [];
function addItem(item) {
$scope.items.push(item);
}
function itemApi() {
return [
{ name: 'apple' },
{ name: 'orange' },
{ name: 'grape' }
];
}
}
angular
.module('typeahead.demo')
.directive('multiSelectTypeahead', multiSelectTypeahead);
function multiSelectTypeahead() {
return {
templateUrl: 'multi-select-typeahead.html',
scope: {
searchApi: '&',
displayNameField: '#',
onSelect: '&',
inputPlaceholder: '#?'
},
link: function ($scope) {
var uibTypeaheadScope;
$scope.initializeScope = initializeScope;
$scope.$watch('isOpen', function (newValue) {
if (!newValue) {
$scope.searchTerm = '';
}
});
function initializeScope(typeaheadPopupScope) {
uibTypeaheadScope = typeaheadPopupScope.$parent;
uibTypeaheadScope.select = selectItem;
}
function selectItem(index, event) {
var selectedItem = uibTypeaheadScope.matches[index].model;
event.stopPropagation();
if (event.type === 'click') {
event.target.blur();
}
uibTypeaheadScope.matches.splice(index, 1);
$scope.onSelect({ item: selectedItem });
}
}
};
}
<!doctype html>
<html ng-app="typeahead.demo">
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-animate.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-sanitize.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.5.0.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<script type="text/ng-template" id="typeahead-search-results.html">
<ul ng-init="$parent.$parent.initializeScope(this)"
class="dropdown-menu"
ng-show="isOpen() && !moveInProgress"
ng-style="{ top: position().top + 'px', left: position().left + 'px' }"
role="listbox"
aria-hidden="{{ !isOpen() }}">
<li class="uib-typeahead-match"
ng-repeat="match in matches track by $index"
ng-class="{ active: isActive($index) }"
ng-mouseenter="selectActive($index)"
ng-click="selectMatch($index, $event)"
role="option"
id="{{ ::match.id }}">
<div uib-typeahead-match
index="$index"
match="match"
query="query"
template-url="templateUrl"></div>
</li>
</ul>
</script>
<script type="text/ng-template" id="multi-select-typeahead.html">
<input type="text"
placeholder="{{::inputPlaceholder}}"
ng-model="searchTerm"
ng-model-options="{debounce: 500}"
uib-typeahead="result as result[displayNameField] for result in searchApi({ searchText: $viewValue })"
typeahead-is-open="isOpen"
class="form-control"
typeahead-popup-template-url="typeahead-search-results.html" />
</script>
<body>
<div ng-controller="TypeaheadDemo" style="padding-top: 15px;">
<multi-select-typeahead class="col-xs-6"
search-api="itemApi(searchText)"
display-name-field="name"
on-select="addItem(item)"
input-placeholder="Search Items...">
</multi-select-typeahead>
<div class="col-xs-6">
<ul class="list-group">
<li class="list-group-item" ng-repeat="item in items">
{{ item.name }}
</li>
</ul>
</div>
</div>
</body>
</html>

JqueryMobile Loader/spinner while loading another page

Searched for almost 2 days and cant able to find a suitable answer.
I am developing a Jquery Mobile page. Currently I have 2 JQuery Mobile pages. When the page is launched it will show a button. Hitting the button will send a SOAP request to the server to get a response. After receiving the response the second page will be displayed.
The SOAP request might take a minimum of 3 to 5 seconds. During that time I would like to show a loader/spinner on the centre of the page till I get the response from the server. How to do that? Following is the code I use.
HTML File containing 2 pages
<form name="frm_login" action="" method="post">
<div id='pg_login' data-role="page">
<div data-role="content">
<input type="submit" name="btn_login_submit" id="btn_login_submit" value="Login" />
</div>
</div>
<div id='pg_menu' data-role="page">
<div data-role="header" data-position="fixed">
<h1>Welcome</h1>
</div>
</div>
</form>
Javascript code as below
$(document).ready(function() {
$('form').submit(function(e){
e.preventDefault();
var xmlRequest = getXmlRequest();
loadingStart();
$.soap({
url: 'full wsdl url',
method: 'getUserName',
data: xmlRequest,
success: function(xmlResponse) {
loadingEnd();
$.mobile.changePage('#pg_menu');
},
error: function(xmlResponse) {
}
});
return false;
});
});
function loadingStart(){
$.mobile.loading( 'show', {
text: "loading",
textVisible: true
});
}
function loadingEnd(){
$.mobile.loading( "hide" );
}
I also keep a 5 second sleep time in the WSDL function for testing purposes.
The loader is not displaying. Please let me know what is going wrong here.
Regards
Malai
The problem is because of the jQuery SOAP plugin (http://plugins.jquery.com/soap/)
After I change to native AJAX things started working fine with the below code.
$(document).ajaxStart(function() {
$.mobile.loading( 'show', {
text: "loading...",
textonly: false,
textVisible: true,
theme: 'a',
html: ""
});
});
$(document).ajaxStop(function() {
$.mobile.loading('hide');
});

Why can't I change page after submitting form?

I should see: "Hello" after hitting submit, but I don't. Why?
http://jsfiddle.net/GbfLG/1/
<div data-role="page" id="create">
<script type="text/javascript">
alert("HERE");
$('#form').submit(function() {
$.post("/").success(function(resp) {
alert("RET");
$.mobile.changePage($("#final"));
});
return false;
});
</script>
<div data-role="content">
<form id="form">
<input type="submit" name="g" value="Submit" id="g"/>
</form>
</div>
</div>
<div data-role="page" id="final">
Hello
</div>​
jQM has a different set of rules then the normal web page. You have used your java script in the wrong place. With jQM, if possible write all you js code in separate file/files.
This is a fix made to your jsFiddle code, it is working now, I have just put it in right context. Your js code was not changed a bit.
Example:
$('#create').live('pagebeforeshow',function(e,data){
$('#form').submit(function() {
$.post("/").success(function(resp) {
$.mobile.changePage($("#final"));
});
return false;
});
});
Your form is submiting - the return false; isn't working as it should.
Try..
$('#form').submit(function(e) {
e.preventDefault();
e.stopPropagation();
... stuff ...
});
Also in your fiddle you haven't defined $.changePage so it comes out as 'undefined'.

Resources