Okay let me be honest as i am a beginner in angular i am not sure how to frame this question i will try my best to explain this question.
Pic 1 :
As you see in the above pic i have a situation where I have a list of classes, and each class will have no of sections under it. you can see a blue button on each row on clicking which i need to know which 'section' was selected.
This is the problem statement.
Now here is the HTML I have for this
<table class="table table-hover">
<tbody>
<tr>
<th>Syllabus</th>
<th>{{phrase.className}}</th>
<th>Select Section</th>
<th>{{phrase.Operations}}</th>
</tr>
<tr ng-repeat="class in classes| filter:searchText">
<td id="syl">
<span ng-repeat="(sid, syllabi) in syllabus" ng-if="sid == class.classAcademicYear">
{{ syllabi.yearTitle}}
</span>
</td>
<td id="cls">{{class.className}}</td>
<td id="sec">
<div class="form-group">
<select class="form-control" name="student_section" ng-model="selectedSection">
<option ng-selected='class.sections[$index].id' ng-repeat="(key, section) in class.sections" value="{{section.id}}">{{section.sectionName}}</option>
</select>
</div>
</td>
<td id="vew">
<button ng-click="edit(class.id)" type="button" class="btn btn-info btn-flat" title="{{phrase.ReadSchedule}}" tooltip><i class="fa fa-fw fa-th-list"></i></button>
</td>
</tr>
<tr ng-show="!classes.length">
<td class="noTableData" colspan="3">{{phrase.NoClasses}}</td>
</tr>
</tbody>
</table>
Here we see a nseted ng-repeat where i am creating table rows based on the list of classes, now this class object also holds the section object inside as you can see inner ng-repeat uses that classes.sections to iterate the options
Now the classes json object is as shown below
[{
"id": 11,
"className": "Class-1 (STATE)",
"classAcademicYear": 2,
"classSubjects": "[\"1\",\"2\",\"3\",\"4\",\"5\",\"6\"]",
"dormitoryId": null,
"sections": [{
"id": 11,
"sectionName": "Section -1 (STATE)",
"sectionTitle": "section title -1",
"classId": 11,
"teacherId": "[\"10\",\"11\",\"12\",\"13\",\"14\",\"15\"]"
}]
}, {
"id": 12,
"className": "Class-2",
"classAcademicYear": 2,
"classSubjects": "[\"0\"]",
"dormitoryId": null,
"sections": [{
"id": 12,
"sectionName": "Section -1",
"sectionTitle": "section title -1",
"classId": 12,
"teacherId": "[\"0\"]"
}]
}, {
"id": 13,
"className": "Class-3",
"classAcademicYear": 2,
"classSubjects": "[\"0\"]",
"dormitoryId": null,
"sections": [{
"id": 13,
"sectionName": "Section -1",
"sectionTitle": "section title -1",
"classId": 13,
"teacherId": "[\"0\"]"
}]
}, {
"id": 14,
"className": "Class-4",
"classAcademicYear": 2,
"classSubjects": "[\"0\"]",
"dormitoryId": null,
"sections": [{
"id": 14,
"sectionName": "Section -1",
"sectionTitle": "section title -1",
"classId": 14,
"teacherId": "[\"0\"]"
}]
}]
What I am trying to do is set a ng-model for the inner select dropdown element that is dynamic , something like below so that every time the section is selected i can set the blue button action to whatever section id is.
ng-model="selectedSection[class.id]"
which is not working.
I know this might not be sufficient information but if some one is interested to help solve me this i can share further details.
For checking what ng-repeat line was selected you should send values $index and $parent.$index (if you have nested ng-repeat).
<button ng-click="edit($index, $parent.$index)" type="button">
Does it help?
Related
I am making angular application and building of angular dynamic form.
Here i am trying to split of form in two parts such as Person Name and Personal details..
For Person Name its working for grouping but for Personal details its not working.
The Html:
<div *ngIf="form">
<div *ngFor="let question of questions" class="form-row" [formGroup]="form">
<ng-container *ngIf="!question.children">
<app-question [question]="question" [form]="form"></app-question>
</ng-container>
<ng-container *ngIf="question.controlType === 'group' && question.children && question.children.length > 0">
<app-dynamic-group [questions]="question.children" [form]="form.controls[question.key]" [key]="question.key" [formControlName]="question.key"></app-dynamic-group>
</ng-container>
</div>
</div>
JSON:
jsonData: any = [
{
"elementType": "group",
"key": "person_name",
"children": [
{
"elementType": "textbox",
"class": "col-12 col-md-4 col-sm-12",
"key": "first_name",
"label": "First Name",
"type": "text",
"value": "",
"required": true,
"minlength": 3,
"maxlength": 20,
"order": 1
},
{
"elementType": "textbox",
"class": "col-12 col-md-4 col-sm-12",
"key": "last_name",
"label": "Last Name",
"type": "text",
"value": "",
"required": true,
"order": 2
}
],
},
{
"elementType": "group",
"key": "personal_details",
"children": [
{
"elementType": "textbox",
"class": "col-12 col-md-4 col-sm-12",
"key": "email",
"label": "Email",
"type": "text",
"value": "",
"required": true,
"minlength": 3,
"maxlength": 20,
"order": 1
},
{
"elementType": "textbox",
"class": "col-12 col-md-4 col-sm-12",
"key": "mobile",
"label": "Mobile",
"type": "text",
"value": "",
"required": true,
"order": 2
}
],
},
];
The working Stckblitz: https://stackblitz.com/edit/angular-x4a5b6-5uj52y
As of working everything works fine.. Already a group was made for Person name and its working fine but for Personal details i am unable to find the input boxes..
A single form needs to get split up with titles above each part thats the requirement of this form.
Here the {{question.key}} displays the name on each input boxes but i need to display only Person Name at top.. Because it is the parent title and the remaining such as First Name, Last Name are input box labels.. How to show the parent title alone in before of each part (Person Name (Has First and Last Name) , Personal Details (Has Email and Mobile))...
I would like to have order split up exactly like the below with title for each respectively.
Person Name
-> First Name
-> Last Name
Personal Details
-> Email
-> Mobile Number
If i am wrong with the above approach then kindly help me to split this https://stackblitz.com/edit/angular-x4a5b6-geesde dynamic form like the below given approach..
My form needs to look like this https://stackblitz.com/edit/angular-zc34qr but it needs to be in pure angular dynamic form and JSON loading..
Kindly help me to create a group Personal Details like the Person Name which was already created and working..
Stuck for a long duration in this kindly help me please...
I don't understand why you creates additional formGroup here:
this.form = new FormGroup({main: innerForm});
Just use formGroup you're getting from your service:
dynamic-form.component.ts
this.form = this.qcs.toFormGroup(this.questions);
dynamic-form.component.html
<app-dynamic-group [questions]="questions" [form]="form"></app-dynamic-group>
Now, you do not need to implement ControlValueAccessor on your DynamicGroupComponent. You're passing FormGroup to it and it should be enough to generate form dynamically.
dynamic-group.component.ts
#Component({
selector: 'app-dynamic-group',
templateUrl: './dynamic-group.component.html'
})
export class DynamicGroupComponent {
#Input() form: FormGroup;
#Input() questions: QuestionBase<any>[] = [];
}
dynamic-group.component.html
<div *ngFor="let question of questions" class="form-row">
<app-question *ngIf="!question.children" [question]="question" [form]="form"></app-question>
<app-dynamic-group
*ngIf="question.controlType === 'group' && question.children && question.children.length"
[form]="form.get(question.key)"
[questions]="question.children">
</app-dynamic-group>
</div>
Forked Stackblitz
I have 3 collections and one object
#
scope.quessionary={};
$scope.jobquestions=[{"id": 2,
"category": "raju",
"question": "haii?",}];
$scope.companyquestionsquestions=[{"id": 2,
"category": "ramu",
"question": "hello?",}];
$scope.departmentquestions=[{"id": 2,
"category": "somu",
"question": "hello?",}];
Now i have to display the category and question field values inthe all collections in one table how can i display ?
You can do something like this:
$scope.quessionary = [];
$scope.quessionary = $scope.quessionary.concat($scope.jobquestions).concat($scope.companyquestionsquestions).concat($scope.departmentquestions);
And in the html:
<table>
....
<tr ng-repeat="question in quessionary">
<td>{{question.category}}</td>
<td>{{question.question}}</td>
</tr>
<table>
I have a json as following.
{
"id":14,
"discussion":8,
"parent":0,
"userid":2,
"subject":"communication skill discussion 2",
"message":"<p>hi all to communication discussion 2 </p>",
"children":[
24,
16,
15
]
},
{
"id":15,
"discussion":8,
"parent":14,
"userid":2,
"subject":"Re: communication skill discussion 2",
"message":"<p>hiiiiiiiiii</p>",
"children":[
25,
23
],
},
{
"id":23,
"discussion":8,
"parent":15,
"userid":2,
"created":1461562317,
"modified":1461562317,
"mailed":0,
"subject":"Re: communication skill discussion 2",
"message":"<p>helloooo</p>",
"children":[
],
}
I want first fetch the details whose Ids matches with the elments in children array
such as for id:14 there are 3 children 24,16,15.Then the control should go directly to id:15 and fetch details of id:15.Again id has children eg. consider id:23 which has no children and will directly print the message.
Please guide me how will I achieve this using ng-repeat of angular ?
Refer to the demo.
Please find the code below:
HTML:
<div ng-app="app" ng-controller="test">
<div ng-repeat="(key,value) in data">
{{key + 1}}) --
<span ng-if="value.children.length > 0">
{{value.children}}
</span>
<span ng-if="!(value.children.length > 0)">
No children found!!
</span>
</div>
</div>
JS:
var app = angular.module('app', []);
app.controller('test', function($scope) {
$scope.data = [{
"id": 14,
"discussion": 8,
"parent": 0,
"userid": 2,
"subject": "communication skill discussion 2",
"message": "<p>hi all to communication discussion 2 </p>",
"children": [
24,
16,
15
]
}, {
"id": 15,
"discussion": 8,
"parent": 14,
"userid": 2,
"subject": "Re: communication skill discussion 2",
"message": "<p>hiiiiiiiiii</p>",
"children": [
25,
23
],
}, {
"id": 23,
"discussion": 8,
"parent": 15,
"userid": 2,
"created": 1461562317,
"modified": 1461562317,
"mailed": 0,
"subject": "Re: communication skill discussion 2",
"message": "<p>helloooo</p>",
"children": [
],
}];
});
UPDATE: As per the request
Demo
HTML:
<div ng-app="app" ng-controller="test">
<div ng-repeat="(key,value) in data">
[{{key + 1}}] --
<div ng-if="value.children.length > 0">
<div ng-repeat="item in value.children">
<span>{{item}}</span> <span class="green" ng-bind-html="getMessage(item)"></span>
</div>
</div>
<span ng-if="!(value.children.length > 0)">
No children found!!
</span>
<br />
</div>
</div>
JS:
$scope.getMessage = function(itemId) {
var flag = true;
var msg;
angular.forEach($scope.data, function(value, key) {
if (flag && value.id == itemId) {
flag = false;
msg = value.message;
}
});
return $sce.trustAsHtml(msg);
}
CSS:
.green {
color: green;
}
Use ng-repeat to display the records.
<ul ng:controller="Cntl">
<li ng:repeat="item in data">
{{item.subject}}: Parent
<ul>
<li ng:repeat="child in item.children">{{child}} : Children
</li>
</ul>
</li>
This is one of the way to display in html. Based on your page design ng-repeat will change.
You can use lodash or underscore _.where:
<div ng:controller="Cntl">
<div ng:repeat="item in data">
{{item.subject}}<br/>
Children
<div ng:repeat="child in item.children">{{_.where(data, {id:child});}}
</div>
</div>
First you need to restructure your json into a tree structure. May be you want to have a look at this post. Then you have to recursively add templates
view
<tr ng-repeat="row in rows" >
<td> {{row.ID}} </td>
<td> {{row.customer}} </td>
<tr>
<button ng-click="quit()">
controller
$scope.rows = [{
"ID": 12,
"customer": "abc",
},{
"ID": 13,
"customer": "klm",
},{
"ID": 14,
"customer": "xyz",
}];
I add new row to the list as follow (it works):
Socket.on('delete', function(ID, customer) {
$scope.rows.push({"ID": ID, "customer": customer});
});
$scope.quit = function() { //code ???? }
My purpose is:
(1) each new row should be displayed with colored background (red) and should get an close-button (x) to quit the new row. clicking to this button, the backgroundcolor should reset the backgroundcolor to none and the button should be hide.
(2)
Which code is needed to quit all new rows with the general button (1 click = reset all red row background to none)
If I understand the problem then you need something like
this:
http://plnkr.co/edit/TuWCf8gpYpMXfuUbsYmz?p=preview
I have a simple ng-repeat iterating through an array of objects.
The ng-repeat contains a ng-model input element for which I need to use a dynamic value as the array index. Probably very unclear explanation so here is the code :
<div ng-repeat="property in current_data.object_subtype.object_property_type" ng-init="set_input_state()" class="input-group ng-scope disabled">
<span class="input-group-addon">{{property.name}}</span>
<input type="text" placeholder="{{property.name}}" ng-model="current_data.properties[getIndexFromId(current_data.properties, property.object_property_type_id)].value" class="form-control" disabled="disabled">
The problem is that the input stays empty. I've tested some combinations and found this to work :
getIndexFromId(current_data.properties, property.object_property_type_id) == 0
current_data.properties[0].value gives the expected output
So somehow getIndexFromId(current_data.properties, property.object_property_type_id)is not well accepted by Angular or I made a stupid mistake somewhere ...
Does anyone know what's wrong with this?
Thanks!
[edit]
Here is a sample of the data behind all this :
{
"id": 1,
"name": "Robert Smith",
"object_subtype_id": 1,
"object_subtype": {
"id": 1,
"description": "Manager",
"object_property_type": [
{
"id": 1,
"description": "Phone number"
},
{
"id": 2,
"description": "Hair color"
},
{
"id": 3,
"description": "Nickname"
}
]
},
"properties": [
{
"id": 1,
"value": "819-583-4855",
"object_property_type_id": 1
},
{
"id": 2,
"value": "Mauves",
"object_property_type_id": 2
},
{
"id": 3,
"value": "Bob",
"object_property_type_id": 3
}
]
}
From what I've seen of Angular, the content of the attributes are not executed as javascript. It's a custom parsed and executed mini-language that doesn't support complex indexing.
With that said, its probably for the best. Any sufficiently complex logic should be handled by the controller or a service.
function MyController($scope) {
$scope.set_current_data_value = function (current_data, property) {
var index = $scope.getIndexFromId(current_data.properties, property.object_property_type_id);
current_data.properties[index].value = $scope.property_name;
}
}
Then your html would look something like:
<input type="text" placeholder="{{property.name}}" ng-model="property_name" ng-change="set_current_data_value(current_data, property)" class="form-control" disabled="disabled">
You may also be able to use ng-submit if you don't need to update your model in real time.