Angular 2+ - Adding DOM elements dynamically in HTML FORM - javascript

I am trying to create a page which users can use to create custom forms. I will be giving the user a drop-down menu. From that drop-down menu, user will be able to select the type of question - like text box, radio button, check box, date and etc. - and then based on that selection, I want to add that type of input into my DOM form.
On submit, I want to store the value of these questions in JSON format.
Any suggestions? What is best approach to tackle this or how I can implement it?

You don't need any package, the best way to do this is like this:
<div ngbDropdown class="nav-item dropdown cursor">
<a class="nav-link" ngbDropdownToggle>
DropDown
</a>
<div ngbDropdownMenu class="dropdown-menu">
<a class="dropdown-item" (click)="option1 = !option1">
Form 1
</a>
<a class="dropdown-item" (click)="option2 = !option2">
Form 2
</a>
</div>
</div>
<form #form="ngForm">
<div class="form-option1" *ngIf="option1Selected">
<!-- YOUR FORM 1 -->
</div>
<div class="form-option2" *ngIf="option2Selected">
<!-- YOUR FORM 2 -->
</div>
...
<button type="submit"></button>
</form>
And them in your component:
option1 = "false";
option2 = "false";
The doc of *ngIf is here

Have a look at ng-dynamic-forms. I've used it on a project before and it really helped creating forms dynamically.
It even provides an import / export functionality which you could use to store the form/questions including the provided answers in JSON format.
sidenote: I am in no way connected to the mentioned project.

EDIT: I feel an example like in this stackblitz shows how much control you have in terms of dynamic forms with the basic Angular utilities.
https://stackblitz.com/edit/deep-nested-reactive-form?file=app%2Fapp.component.html
Reactive Forms are your answer. There is no perfect way to do what you want. But I picked out a particular piece of an example from an old project. So, on one point I check for the type of comparators I have available due to my first choice. After that I check if I need a field that requires a simple input field or a datepicker. There are SO many ways to do this.
<div class="col-7">
<!-- Text Input Field for most cases that don't involve time comparisons -->
<div *ngIf="!doesRequireDateInput(i) && checkIfComparatorOptionIsEmptyOrNull(i)">
<div class="string-input-field" formArrayName="values">
<div [formGroupName]="j" *ngFor="let val of getValues(condition); let j = index">
<div class="input-group">
<input formControlName="value" type="text" class="form-control py-0" placeholder="Search for...">
</div>
</div>
</div>
</div>
<!-- Date Input Field -->
<div *ngIf="doesRequireDateInput(i) && checkIfComparatorOptionIsEmptyOrNull(i)">
<div class="string-input-field row" formArrayName="values">
<div [formGroupName]="j" *ngFor="let val of getValues(condition); let j = index">
<div *ngIf="j === 0" class="input-group mb-3">
<input type="text" formControlName="value" name="dateFrom" class="form-control py-0" style="text-align: center" [owlDateTimeTrigger]="dt3"
[owlDateTime]="dt3">
<owl-date-time [pickerType]="'calendar'" #dt3></owl-date-time>
<div class="input-group-append">
<span class="input-group-text" style="border-bottom-right-radius: 0px; border-top-right-radius: 0px" id="date-for-input">
<i class="fa fa-calendar" aria-hidden="true"></i>
</span>
</div>
</div>
<div *ngIf="j === 1" class="input-group mb-3">
<input type="text" formControlName="value" name="dateFrom" class="form-control py-0" style="text-align: center" [owlDateTimeTrigger]="dt3"
[owlDateTime]="dt3">
<owl-date-time [pickerType]="'calendar'" #dt3></owl-date-time>
</div>
</div>
</div>
</div>
</div>

Related

Autocomplete like Basecamp?

I'm currently learning website design, I have started creating my own Basecamp like website (project management tool). I am in need of a plugin or a tutorial on autocomplete input javascript like Basecamp... however i'm unsure on how to set this up as i'm super new to javascript and still trying to get my head around it all.
Use the multiple search selection feature from Semantic UI's dropdown module:
https://semantic-ui.com/modules/dropdown.html#multiple-search-selection
Here's a sample jsfiddle: https://jsfiddle.net/9wnjra1z/
<form class="ui form">
<div class="field">
<label>Assigned to</label>
<div class="ui fluid multiple search selection dropdown">
<input type="hidden" name="users" />
<i class="dropdown icon"></i>
<div class="default text">Select Users</div>
<div class="menu">
<div class="item" data-value="kristin_aardsma">
<img class="ui avatar image" src="https://semantic-ui.com/images/avatar/small/jenny.jpg">
<span>Kristin Aardsma</span>
</div>
<div class="item" data-value="jonny_cyrus">
<img class="ui avatar image" src="https://semantic-ui.com/images/avatar/small/elliot.jpg">
<span>Jonny Cyrus</span>
</div>
<div class="item" data-value="stevie">
<img class="ui avatar image" src="https://semantic-ui.com/images/avatar/small/stevie.jpg">
<span>Stevie</span>
</div>
<div class="item" data-value="matt">
<img class="ui avatar image" src="https://semantic-ui.com/images/avatar/small/matt.jpg">
<span>Matt</span>
</div>
</div>
</div>
</div>
</form>
You will need the following references in your code to use this library:
https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js
https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.css
https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.js

Show input with ng-show when select some value from dropdown

I'm getting info from json and printing on a dropdown. Next, my code:
function firstCombo (){
$http.get('app/combo.json')
.then(function(data){
vm.dataCombo = data.data;
//console.log(vm.dataCombo);
});
}
On my html view:
<div class="col-md-4 col-md-offset-3"> What is this?
<button type="button" id="options1" aria-expanded="false" aria-haspopup="true" role="button" data-toggle="dropdown" class="btn btn-default dropdown-toggle">
Select one <span class="caret"></span>
</button>
<ul class="dropdown-menu" id="list1">
<li ng-repeat="dea in $ctrl.dataCombo">{{dea.value}}</li>
</ul>
</div>
The returned values are just 3:
Apple
Orange
Mango
What i want to do, is to show an input if the user selects "Apple":
<div class="row" ng-show="false">
<div class="col-md-4">What kind of apple?<input type="text" class="form-control"></div>
</div>
Right now, is hidden with ng-show="false", but, what am i have to do to show/hide the input if the value of dropdown is "Apple"? Guess is very simple, but right now, i'm in blank.
Thanx in advance.
you can use ng-if rather than ng-show/hide option.This is one of best practice in AngularJs
<div class="row" ng-if="selectedValue=='Apple'">
<div class="col-md-4">What kind of apple?<input type="text" class="form-control"></div>
</div>

How to submit a form in one tab and see results in next tab?

There are three tabs on page. Input,output and review. Html form is in input tab where user enter input in text box. I want to calculate something from that input value and display it in next tab OUTPUT by clicking submit button.
I already have that file which will do the calculation with that input.
Answers are really appreciated.
<div class="container tabs-wrap">
<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="active">
Input
</li>
<li>
Output
</li>
<li>
Review & Email
</li>
</ul>
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="input">
<h2>Web based two tier ground mount bill of material generator</h2>
<form class="form-horizontal" action="output.php" method="post" target="_blank">
<div class="form-group">
<label class="control-label col-sm-2" for="count">Module Count:</label>
<div class="col-sm-10">
<input type="number" class="form-control" id="count" placeholder="Enter Number of Modules" name="count">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-primary continue">Continue</button>
</div>
</div>
</form>
Try this,
$(function() {
$('#btnSubmit').on('click', function() {
// your code goes here
$('#outputSpan').text($('#count').val());
// not triiger output tab to be open
$('[href="#output"]').trigger('click');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<div class="container tabs-wrap">
<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="active">
Input
</li>
<li>
Output
</li>
<li>
Review & Email
</li>
</ul>
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="input">
<h2>Web based two tier ground mount bill of material generator</h2>
<form class="form-horizontal" action="output.php" method="post" target="_blank">
<div class="form-group">
<label class="control-label col-sm-2" for="count">Module Count:</label>
<div class="col-sm-10">
<input type="number" class="form-control" id="count" placeholder="Enter Number of Modules" name="count">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" id="btnSubmit" class="btn btn-primary continue">Continue</button>
</div>
</div>
</form>
</div>
<div role="tabpanel" class="tab-pane" id="output">
<h2>Output</h2>
<span id="outputSpan"></span>
</div>
</div>
</div>
Based on your code you should have all three tabs in one html file (not separate files). Have a look here for more info.
You could attach a function to the "continue" button that handles the calculation
$(".continue").on("click", function () {
//Handle calculation, changing tabs and writing results here
// do your calculations here
$('.nav-tabs a[href="#output"]').tab('show'); // change active tab
$( '.resultElemClass' ).text('calculationValue'); // output the result
});
One possible way to do this:
onFormSubmit(calculatedValue){
$('#output').html(calculatedValue);
}
The logic is that when you successfully submit a form, make sure that you append the calculated value to the #output, or which ever div you want to append it to.
If you are using AJAX to communicate with PHP, it would look something like this:
$.ajax({
url: "file.php",
type: "post",
data: values,
success: function (response) {
// you will get calculated value from your php page (what you echo or print)
$('#output').html(response);
}
});
Assuming the output tab is another view file, you can use export function of javascript. Like take the input process it as per your needs and then use function like:
// file1.js
export function value() {
return "Your output";
}
file1 is where you will be accepting input or processing the input
// output.js
import {hello} from 'file1'; // or './file1'
let val = value(); // val is Your output;
Make sure to put an 'if' in your output file and refresh it after a certain time interval(1 sec or so) so get the value as soon as it is available.

Clear Form Input Inside ng-repeat AngularJS

A part of our website includes users replying to reviews posted by other users. All replies(inputs) are bound to the same ng-model. In the HTML code, there's a form that is repeated, over and over again using ng-repeat. The problem is that after a user posts a reply the form doesn't get cleared, so the next user replying to the review, is left with a box that includes the review of the previous user, and therefore has to override it.
Here's our HTML code:
<li ng-repeat="reply in review.replies">
<div class="comment-avatar">
<img src="http://i9.photobucket.com/albums/a88/creaticode/avatar_2_zps7de12f8b.jpg" alt="">
</div>
<div class="comment-box">
<div class="comment-head">
<h6 ng-if="reply.authorType == 'user'" class="comment-name">{{reply.user.name}}</h6>
<h6 ng-if="reply.authorType == 'business'" class="comment-name by-author"> {{business.name}}</h6>
<span style="margin-top: 10px">{{reply.timestamp | date: 'd MMM, yy h:mm a ' }}
<i ng-click="deleteReply(review, reply)" class="delete glyphicon glyphicon-trash"></i>
</span>
</div>
<div class="comment-content">
{{reply.reply}}
</div>
</div>
</li>

How to compare the needed data by selecting check box and to show in list view

I have two check boxes. 1. filter by data, 2. Show pending.. Below that I am populating some data from database in list view. What I need is, if I press filter by data check box, then my list view should reload and show the data from data format. Means that the data which is added first in the database should show first in list view.
In my database I have one parameter called status, which will show the status pending or ordered. So, if I press show pending check box, then the records having pending status, should populate in my list view. Here is my code :
<div class="row" >
<div class="col col-50" style="border-right: 1px #ccc solid;">
<input type="checkbox" style="margin: 8px;"> <span class="assertive" style="margin: 0px;">Show pending</span>
</div>
<div class="col col-50">
<input type="checkbox" style="margin: 8px;"> <span class="assertive" style="margin: 0px;">sort by date</span>
</div>
</div>
<ion-list>
<ion-item class="item-icon-right clsOrders" ng-repeat="mydash in MyOrders" ng-click="ShowDetails(mydash)">
<div class="row" >
<div class="col col-20 clsOrderDateMonth">
<span class="clsOrderDate">{{mydash.dateAdded}}</span>
<div class="spacer" style="height: 5px;"></div>
<span class="assertive clsOrderMonth">{{mydash.monthAdded}}</span>
</div>
<div class="col col-50">
<span class="balanced clsOrderDetailNumber">{{mydash.customerName}}</span>
<div class="spacer" style="height: 10px;"></div>
<div class="clsStatusCount row cls0Padding">
<div class="col col-50 cls0Padding">
Item: <span class="assertive">{{mydash.productCount}}</span>
</div>
<div class="col col-40 cls0Padding">
<span class="balanced clsMakeContentRight">{{mydash.orderStatus}}</span>
</div>
<div class="col col-20 cls0Padding">
</div>
</div>
</div>
<div class="col col-25 ">
<div class="spacer" style="height: 5px;"></div>
<div class="col col-40 cls0Padding" style="margin-top: 26px;font-size: 11px;">
Amount: <span class="assertive">{{mydash.orderTotalAmount}}</span>
</div>
</div>
</div>
<i class="icon ion-chevron-right icon-accessory"></i>
</ion-item>
</ion-list>
How can I do that?
For UI:
I think you have to associate an action function for checkbox change event.
If you use, <ion-checkbox> you have ionChange event to execute necessary data processing logic, like this:
<ion-checkbox (ionChange)="processData(parameters)">
</ion-checkbox>
Check out the documentation and this issue on ionic forum.
Also, check if (click)="processData(parameters)" works. Not tested this though.
In the list below, UI should be simple enough by using ngFor and ngIf.
Script
Now, the data you are supposed show in list has to be manipulated in this processData(parameters) method.
Note: But, looking at your use case, I am not sure you are using the correct design. Maintaining status of pending/ordered for one device is fine. But data will get invalid for multiple devices, as different devices' status for what data has loaded and what data is pending will vary. Need more help here understanding the exact use case though.

Categories