How to create and add html elements dynamically with angular - html

I am trying to build a shopping web app as a project for my master degree.
So my problem is that when I click the button to add a category(calling the function addCategory in my .ts file) I don't know how to create a div and add it to the html file with the id of the category's name, from the .ts file.
Any help it's welcomed.
<div class="container">
<div class="row">
<div class="col-6">
<h1>Products</h1>
<button (click)="addCategory()">Add category</button>
<div id="Products">
</div>
</div>
<div class="col-6">
<h1>Shopping basket</h1>
<div id="Shoppingbasket">
<table id="Productstable" class="table table-bordered">
<thead>
<tr>
<th scope="col">Image</th>
<th scope="col">Name</th>
<th scope="col">Price</th>
<th scope="col">Units</th>
<th scope="col">Description</th>
</tr>
</thead>
<tbody id="Productstablebody">
</tbody>
</table>
</div>
</div>
</div>
</div>

I'd suggest looking at the Tour of Heroes tutorial on the Angular web site to learn more.
You can create a list in your component, call it categories, then add more categories when you click the addCategory button. In your html template, you can loop through the categories and create an element for each of them.
I created a minimal example in a Stackblitz. Below is a rough example of how it can be done
Angular component
categories: string[] = [];
addCategory() {
this.categories.push('category');
}
HTML template
<div *ngFor="let category of categories">
{{category}}
</div>

make an array of category;
when you click add category add to the array then loop it in html like these
<div *ngFor="let category of categories" [id]="category.name">
</div>

Related

Drag & Drop - Merge Rows on Drop - Angular

I've a three level folder structure implemented to resemble hierarchical levels in a Angular Project and trying to achieve drag & drop on this folder structure to merge them on dragging & dropping onto each other.
I've tried adding HTML Drag & Drop APi's but that doesn't help in merging the content of dropped folder ideally.
<table class="table table-bordered table-striped">
<ng-container *ngFor="let content of contents">
<tr class="top-row">
<td class="parent"><i id="parentFolder" class="fa fa-folder-open"></i>{{content.title}}</td>
</tr>
<ng-container *ngFor="let subFolder of contents['subfolder']">
<tr class="object-row">
<td class="child"><i id="childFolder" class="fa fa-folder-open"></i>{{subFolder.title}}</td>
</tr>
<tr *ngFor="let product of subfolder['innerFolder']">
<td class="secondchild"><i class="fa fa-folder"></i>{{product.title}}</td>
</tr>
</ng-container>
</ng-container>
</table>
I was able to achieve this using Angular 2 Drag-and-Drop without dependencies.(https://github.com/akserg/ng2-dnd)
it has draggable & droppable directives to replicate the native HTML DnD APIs as well as restricting drop zones as well as callback functions to allow the drop functions
<table class="table table-bordered table-striped">
<ng-container *ngFor="let content of contents">
<tr class="top-row">
<td class="parent"><i id="parentFolder" class="fa fa-folder-open"></i>{{content.title}}</td>
</tr>
<ng-container *ngFor="let subFolder of contents['subfolder']">
<tr class="object-row" ***dnd-draggable [dragEnabled]="true"***>
<td class="child" **dnd-droppable (onDropSuccess)="simpleDrop=$event"**><i id="childFolder" class="fa fa-folder-open"></i>{{subFolder.title}}</td>
</tr>
<tr *ngFor="let product of subfolder['innerFolder']">
<td class="secondchild"><i class="fa fa-folder"></i>{{product.title}}</td>
</tr>
</ng-container>
</ng-container>
</table>

Filling all input fields

There is a markup:
<div class="scroll">
<table class="table table-striped">
<thead>
<tr>
<th>Image</th>
<th>Name</th>
<th>Author</th>
<th>Year</th>
<th>ISBN</th>
<th>Price</th>
<th>Count</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let book of bookService.bookList">
<td><img src="../../{{book.ImagePath}}" width="100" height="150"></td>
<td>{{book.Name}}</td>
<td>{{book.Author}}</td>
<td>{{book.Year}}</td>
<td>{{book.ISBN}}</td>
<td>{{book.Price}}</td>
<td>{{book.Count}}</td>
<td>
<input type="text" name="Count" [(ngModel)]="Count">
<button class="btn btn-block btn-outline-success" (click)="onAdd(book, Count)"><i class="fa fa-plus"></i></button>
</td>
</tr>
</tbody>
The last column looks like this:
The problem is the following: when filling one TextBox, all the TextBoxes in the column are filled.
How can I solve this problem? Tried to give unique names to text fields and to thrust this cell in form, but all the same did not work.
You need to give unique name to the input field using angular template
<input [name]="'count' + i" >
Where i is the index from the *ngFor
But I think the major issue you have is that you need to bind book.Count instead of just Count
In latter case you'll have one variable called Count and you bind the same variable to all of the input fields. You need to attach the variable to the book itself so it is unique.
All your inputs have the same [(ngModel)]="Count" and the same name so if you update one, all of them will be updated
You can fix that if you have an array of count instead. So it will be something like
<tr *ngFor="let book of bookService.bookList; let i = index">
...
<input type="text" [name]="'count' + i" [(ngModel)]="count[i]">
People are giving you the HTML way, I'm giving you the Angular way : trackBy functions.
*ngFor="let book of bookService.bookList; trackBy: book.Name"
This one should work but I've never tested it.
The one should work in any case :
*ngFor="let book of bookService.bookList; trackBy: customTB"
customTB(item, index) {
return `${index}-${item.Name}`;
}
You can't use the same name for your inputs.
To fix this, you can add an id populate by the index of the loop *ngFor
Try this :
<tr *ngFor="let book of bookService.bookList; let i = index">
<input type="text" name="Count_${i}" [(ngModel)]="count">

Suppress display of Table fields in HTML / ASP.NET

I inherited a web app built in ASP.NET which returns a table of query results which pull from a database. Right now, all fields display as text, with the exception of the "Url" column which is a hyperlink (as seen in below code). What code would I add if I wanted to also suppress the display of one of the columns returned (or just not return it at all if that makes more sense)?
EDIT - additional information: the table columns are not pre-defined anywhere in the source code. The app has the ability for you to define a database and table from which to pull the results of your query - therefore the resulting table is dynamic. This is why it seems it has to be done in the HTML code of the page itself.
Below is the HTML code for the table:
<div class="row" ng-if="loading || results != null">
<div class="col-lg-2" ng-show="facets">
<div class="widget">
<div class="widget-title">
<i class="fa fa-check-square-o"></i> Facets
</div>
<div class="widget-body xlarge no-padding">
<pre>{{ facets | json }}</pre>
</div>
</div>
</div>
<div ng-class="{ 'col-lg-10': facets != null, 'col-lg-12': facets == null }">
<div class="widget">
<div class="widget-title">
<i class="fa fa-bars"></i> Results <span>({{ count }} results)</span>
</div>
<div class="widget-body xlarge no-padding">
<div class="message" ng-if="!loading && (results == null || results.length == 0)">
<div class="alert alert-warning">The query did not return any results.</div>
</div>
<div class="table-responsive" ng-if="!loading && results != null && results.length > 0">
<table class="table table-hover">
<thead>
<tr>
<th ng-repeat="field in fields">
{{field}}
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="result in results">
<td ng-repeat="field in fields">
<div ng-if="field == 'Url'">
{{ result.DirectSourceUrl }}
</div>
<div ng-if="field !== 'Url'">
{{ result[field] }}
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
I am not a .NET expert but i do know angular so if i get your question right, just ignore the field you wanna delete and don't bind it in the html or you could do something like this in angular controller right after the results are returned response.data.fieldName=undefined; (fieldName is the name off the column you wanna delete.
Hope it helped you.

how display grids using table

Am using grid to diplay data from my data base. I would display grids in a table of 3 columns inthis way :
I try this code
<table style="width:70%" ng-repeat="e in events" >
<tr>
<td>
<div class="col-md-3 ticket-grid" >
<div class="tickets">
<div class="grid-right">
<font color="red"><h3>{{e.name}}</h3></font>
Location: {{e.loc}}<br>
Category: Sport <br>
Start date: <br>
End date:
Description: <span>{{e.description}}</span> <br>
Contact: {{e.contact}}<br>
Confirm
Refuse
</div>
<div class="clearfix"> </div>
</div>
</td>
</tr>
<tr>
</tr>
<tr>
</tr>
</table>
PS: events is an array that contains my data.
But i get this result
Any help please
You need to add the ng-repeat to the element you want repeated. In your version you are creating new <table> with all contents for each record in events. Moving it to the <td> will leave you with same issue as it will just create a new row for each record.
If you are using bootstrap - you should just use the grid system instead of the <table> for layouts, something like.
<div ng-repeat="e in events">
<div class="col-md-4 ticket-grid" >
<div class="tickets">
<div class="grid-right">
<font color="red"><h3>{{e.name}}</h3></font>
Location: {{e.loc}}<br>
Category: Sport <br>
Start date: <br>
End date:
Description: <span>{{e.description}}</span> <br>
Contact: {{e.contact}}<br>
Confirm
Refuse
</div>
<div class="clearfix"> </div>
</div>
</div>
You will need something like, to break out of the ng-repeat loop every 3 records:
<div class="clearfix" ng-if="$index % 3 == 0"></div>
See Plunker examples for more of an idea here

Django how can I pass data to hyperlink?

MY TEMPLATE
<div class="row">
<div class="col-lg-9">
<table class="table table-bordered">
<thead>
<tr>
<th>Title</th>
<th>Publication date</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
{% for questionnaire in questionnaires %}
<tr>
<td>
<div class="checkbox">
<input type="checkbox" name="questionnaires" id="questionnaires" value="{{ questionnaire.id }}">
<label><b><a href="" >{{ questionnaire.name }}</a></b></label>
</div>
</td>
<td>{{ questionnaire.pub_date }}</td>
<td>Delete</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="col-lg-3">
<div class="sidebar-nav-fixed pull-right">
<div class="well">
<ul class="nav ">
<li>
Add new
</li>
<li>
Export to PDF
</li>
<li>
Check results
</li>
<li>
Draw charts
</li>
<li>
Generate tokens
</li>
<li>
Clear results
</li>
<li>
Delete selected
</li>
</ul>
</div>
</div>
</div>
I need to get all checked objects from checkboxes placed in table, and pass them to hyperlinks in navbar.
For example, I have hyperlink "Delete selected". I want to delete every questionnaire which is selected by clicking on that link. Is it possible? If yes how can I do that?
In order to achieve, 'I have hyperlink "Delete selected". I want to delete every questionnaire which is selected by clicking on that link.', it's going to require a mix of jQuery and Django.
You should attach a click listener on the 'Delete selected' button which should serialize all selected questionnaires and send that data via AJAX to a Django view which will delete the necessary questionnaire objects from the database.
Here is a rough example...
<script type="text/javascript">
$(document).ready(function() {
$('.btn-danger').click(function() {
$.post('url/to/django/view', $('input[name=questionnaires]').serialize(), function(data, textStatus, jqXHR) {
// DO STUFF VIA THIS CALLBACK
});
});
});
</script>
def url/to/django/view(self, request):
if request.method == 'POST':
questionnaires_to_delete = request.POST.getlist('questionnaires')
Questionnaire.objects.filter(id__in=questionnaires_to_delete).delete()
return HttpResponse('WHATEVER YOU WANT TO RETURN TO THE CLIENT')
You many run into CSRF issues depending on your setup. Here is the documentation for handling that...
https://docs.djangoproject.com/en/1.7/ref/contrib/csrf/