I have a couple of places on my project where I'm trying to make a form open up from a different html section. I couldn't find any clear answer on how to do this.
To explain more:
After filling in the form, clicking create does work, it creates the new task, and the task is being created on the server, but it won't show up in the table until I refresh the page and reload the HTML. I do have a function to retrieve the tasks from the server, and it runs, all new tasks are stored in my model (main.items), but the HTML doesn't refresh it.
Example 2:
When I click this edit button, it won't open up the form. The delete button does work, and makes the line disappear, but it's in the same table.
The simplified code:
HTML
<div ng-cotroller="MainController as main">
<div>
<button ng-click="main.openForm()">Add New</button>
</div>
<div ng-show="main.showForm">
<form>
...
</form>
</div>
</div>
...
<table ng-cotroller="MainController as main">
<thead><tr><th>...</th></thead>
<tbody>
<tr ng-repeat="item in main.items">
<td>{{item.id}}</td>
...
<td><i class="..." ng-click="main.openForm()></i></td>
</tr>
</tbody>
</table>
Angular
app.controller('MaintenanceController', ['$http', function($http){
var main = this;
main.items = [];
main.showForm = false;
this.getItems = function(){
$http.get(serverUrl+"/items").success(function(data){
main.items = data;
}
this.openForm = function(){
main.showForm = true;
}
}]);
As shown, both the button "Add New" and the icon in the table call the same function, and the value of showForm does change to true in both cases, but the icon does not open the form, as the HTML does not refresh it because it's not in it's tag (my assumption).
Further down the road, once I get the icon to open the form, I also want to insert the details form the same task from the table into the form, so it can be edited. But for now I just want to open the form.
Can anyone tell me what I'm missing, or point me in a direction to get this to work?
The issue occurs due to two instances of the same controller.
You create the first controller:
<div ng-controller="MainController as main">
Then the second one:
<table ng-controller="MainController as main">
Their scopes are not shared. So when one of them gets updated the second stays the same.
IMO, there is no need for two instances here. But if you really want this approach than you will need to either:
create some base controller with items. then both controllers will inherit this collection and all changes will be updated
put collection to factory.
Related
I'm new to Angular. I've got an Angular js form that has rendered and works properly (updates, etc). I have a scenario where I want to populate form values based on user action after the form has rendered. So if the user takes a certain action, the values in a dropdown box, checkbox, input, etc, are preset in a certain way. I can get everything working except the last step.
From javascript, how do I update the data displayed on the form?
I've gone so far as to use
document.getElementById('123').value = 'my new default'
and although that works for plain text input fields, it doesn't change things like select dropdown boxes. They accept the new value, but still display a blank value. Is there any easy way to do this through the Angular framework?
You can update the value on an html form using angularjs like so:
angular.module('HelloWorldApp', [])
.controller('HelloWorldController', function($scope) {
$scope.greeting = "Hello World";
$scope.UpdateForm = function(){
$scope.greeting= "Updated!";
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<html>
<div ng-app="HelloWorldApp">
<div ng-controller="HelloWorldController">
<input ng-model="greeting" />
<button ng-click="UpdateForm()">Update Form</button>
</div>
</div>
</html>
To get started with angular, I really enjoyed watching this video
Angular in 50 examples part 1
I'm developing a Ionic mobile app & I want to pass the button text (which I'll be getting in a ng-repeat) as a string value to the next page and display the variable in the title bar. How do I achieve this? I tried so many solutions from the web resources but still no luck!
<div ng-repeat="x in list">
<button ng-click="callCustomFn(x.text)">
{{x.text}}
</button>
</div>
Create some service and set its custom variable value to the button text clicked from controller and access it in next page
Your controller :-
$scope.callCustomFn = function(text){
myService.setText(text);
}
Inside new page controller :-
$scope.title = myService.getText();
I have this two pages index.html#/view and index.html#/update (view and update are also html files)
Their layout is essentially the same (except that view is for viewing only and update is for editing), they use same directives, search-div with search-div.html as template and result-div with result-div.html
and a common controller PageCtrl
search-div.html
<div>
<form>
<input ng-model="page.id">
<input ng-model="page.type">
<button ng-click="page.cancel()">Cancel</button>
<button ng-click="page.submit()">Submit</button>
</form>
</div>
result-div.html
<div>
<table>
<thead>...</thead>
<tbody>
<tr><td>{{page.retrievedData.id}}</td></tr>
<tr><td>{{page.retrievedData.type}}</td></tr>
// some other retrieved data as rows
// some rows are, for view <td>, for update <input>
<table>
</div>
result-div is obtained by some $http.get.
view.html
<div ng-controller="PageCtrl as page">
<search-div></search-div>
<result-div></result-div>
<button ng-click="page.modify('update', page.id, page.type)">Modify</button>
</div>
update.html
<div ng-controller="PageCtrl as page">
<search-div></search-div>
<result-div></result-div>
<button ng-click="page.save()">Save</button>
</div>
When I click the modify button, the id and type in the search-div of view page should still show on update page, so I did:
(inside PageCtrl)
$scope.modify = function(path, id, type) {
$location.path(path);
$scope.id = id;
$scope.type = type;
};
There was no problem with re-directing to another page, however, the id and type does not reflect in update's search-div. What happens to the $scope from view to update directive? How can I properly pass the values of view $scope to update $scope? I would also like to know how to show result-div in update page with the same result from view page.
I'm starting with AngularJS, and I'm building a multi-step form where user has to fill different pages. When finished a page, he's allowed to press a next button and fill the following page.
For the first page, I've built in the HMTL a form (named pageOneForm), with different text input fields, marked as required, and in the relative controller I'm doing this watch:
$scope.$watch('pageOneForm.$valid', function(validity) {
ModelData.actualPageCompleted = validity;
})
And it works like a charme. My model (ModelData) is updated.
I was trying to apply the same logic to the following part of the app, the second page. Instead of input text, the user has to select two options from 2 different radio buttons groups.
So I built in the html a list of buttons via ng-repeat :
<div ng-Controller="PageTwo" ng-show='data.actualPage == 2'>
<form name="pageTwoForm">
<h3>General Information > Knowledge About </h3>
<div>
<b>User</b>
<div ng-repeat="option in userOptions">
<input type="radio" name="userGroups" ng-model="data.knowledgeAboutUser" ng-value="option.id" id="{{option.id}}" required>{{option.text}}
</div>
<div ng-repeat="option in targetGroupUserOptions">
<input type="radio" name = "targetUserGroup" ng-model="data.knowledgeAboutTargetGroup" ng-value="option.id" id="{{option.id}}" required>{{option.text}}
</div>
</div>
</form>
and I've implemented the same code as above in its controller:
$scope.$watch('pageTwoForm.$valid', function(validity) {
ModelData.actualPageCompleted = validity;
})
but apparently it doesn't work, and in my model actualPageCompleted is always true...
What am I doing wrong?
Thanks
I did my best to create a controller with some dummy data to get a fiddle working with your example code. Here is the fiddle You need to force the $digest cycle to update your form's validity state on ng-click for the radio buttons (see this SO post for more details), which is why the method
$scope.forceDigest = function(){
setTimeout(function(){ $rootScope.$$phase || $rootScope.$apply(); });
};
is necessary. Alternatively, you can get rid of the method call and uncomment the html code
<h3 ng-show="false">{{data.knowledgeAboutTargetGroup}}</h3>
<h3 ng-show="false">{{data.knowledgeAboutUser}}</h3>
in the fiddle to force the form object to update as well.
And I would make sure that ModelData.actualPageCompleted is not retaining its true value from when pageOneForm.$valid became true and it was set.
I hope that this helps!
Problem
I have a form which is divided into five different sections. Find the Image below. When a person comes on this page I direct him/her directly to the Summary stage with pre-populated data which is working fine. Where the problem comes is there's an option for the user to go n edit this form by clicking on prev button. After the user changes the value in the previous stages and comes back to the summary stage it still shows them the default information which came through the pre-populated data but when a user submit form it submits the correct info with new edited data.
Is there any way I can refresh or reload it? I'm using the below code to display this summary.
Code
//Button to reach the summary stage
<button type="button" class="next" id="summary" onclick="loadnext(4,5);"><img src="images/next.jpg" alt="" /> </button>
//Display
<tr>
<td>Team Name</td>
<td id='t_name_SUM'></td>
</tr>
<tr>
<td>Team Visibility</td>
<td id='t_visibility_SUM'></td>
</tr>
To better support my comment I'm writing this answer.
What you need to do is provide a mechanism to collect data step by step. Copying HTML into other elements is not a very flexible way to do that.
I created a jsfiddle to demonstrate the idea. It's far from perfect but at this stage it works without making things to complicated.
The basic idea is to have an object to control the flow of the views(steps) the user needs to handle. Each view has a controller associated with it to handle the data.
The views.
<div id="step1" class="view">
<h3>Step #1</h3>
<input type="text" name="name" value="" />
</div>
<div id="step2" class="view">
<h3>Step #2</h3>
<input type="text" name="title" value="" />
</div>
<div id="step3" class="view">
<h3>Step #3</h3>
<input type="text" name="message" value="" />
</div>
The object controlling the flow (only showing the most relevant parts).
var flow = {
...
settings:{}, // settings to save
routes: [
{controller:Step1Ctrl, element:'#step1'},
{controller:Step2Ctrl, element:'#step2'},
{controller:Step3Ctrl, element:'#step3'}
],
...
show: function (index) {
var route = this.routes[index];
if (this.currentController) {
this.currentController.commit();
}
this.index = index;
this.currentController = new route.controller(
this.settings,
route.element
);
}
};
Every time a new view is shown the current controller commits the changes to settings and a new controller is created for the current view.
A simple controller can look like this.
function Step1Ctrl(settings, element) {
var $e = $(element).find('input[name="name"]');
$e.val(settings.name); //set the initial value
this.commit = function () {
settings.name = $e.val(); //save
};
}
Since every controller now commits it's changes to settings it easy to represent that data in any way you like. The fiddle just alerted the collected data but you can easily create another view and another controller to display thse settings.
Also, because every controller has access to the settings it can act upon values that are already in there or check if a combination of settings is even possible or not.