Angular mat-autocomplete with dynamic inputs - angular-material

I'm new in angular material design and I have a problem with mat-autocomplete for dynamic inputs. By default user see one input but when some value is selected than another input can be added and this is the tricky part - how to make that all those inputs will be using only one mat-autocomplete? Is it possible?
Below is code where I'm using mat-autocomplete. The addItem() function is adding another input which would be bind to the same mat-autocomplete. Should it be moved above ? And what about unique id? How can I solve this issue with multiple inputs connected to the same mat-autocomplete?
<div formArrayName="items" class="form-group"
*ngFor="let item of items.controls; let i = index">
<mat-form-field class="example-full-width">
<input required type="text" placeholder="Item ID"
matInput
[formControlName]="i"
[id]="i"
[matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete">
<mat-option *ngFor="let option of filteredOptions | async"
[value]="option.code"
(click)="selectOption(option, i)">
{{option.code}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
<i *ngIf="i == 0 && selected" class="fa fa-plus add-vessel"
aria-hidden="true"
(click)="addItem()"></i>
<i *ngIf="i !== 0 && canRemove" class="fa fa-minus add-vessel"
aria-hidden="true"
(click)="removeItem(i)"></i>
</div>

You have to use multiple auto complete elements and all the inputs need to bind with array of valueChanges event capturing functions. The reason is if you're trying to bind valueChanges with formArray ("items") then the function will execute number of time that how many inputs in the array. Use the following code to achieve target.
for(var i = 0;i<numberOfInputElements;i++){
const items = this.form.get('items') as FormArray;
this.filteredOptions[index] = items.at(index).get('item').valueChanges
.pipe(
startWith(''),
map((value: string) => (value) ? this._filter(value, this.options) : this.options.slice())
);
}

Related

how to handle subtraction in thymeleaf

I have registration form, where a user can enter her
name,email,dateofBirth,mobile Number. I want to calculate the users
age. If the user is 21 old he is able to register with us unless he cannot able to register. I have already created custom validation, and I pass the validation in my model class. But I am not able to calculate the age and use the logic for 21 year. I created dynamic form.
SignUp.html
<div class="content-area-container page-ath-wrap" th:object="${advertisement}">
<div class="page-ath-content container-fluid">
<div class="page-ath-form">
<div class="page-ath-heading">
<!-- <h3 th:text="*{reward_amount}">Congrats! You just earned $5 off your next beer.</h3>-->
<h3 th:text="*{form_title}"></h3>
<!-- <p>Enter your info to claim the reward!</p>-->
<p th:text="*{form_description}"></p>
</div>
<div class="singup-form">
<form id="form_signup">
<input id="id" th:field="*{id}" type="hidden"/>
<div th:each="item,iterStat : *{form}" >
<!-- <label th:label="${str.getLabel()}" th:type="${str.getType()}" th:text="${str.value}" ></label>-->
<div class="form-group">
<label th:for="${item.name}" th:text="${item.label}"></label>
<div th:if="${item.validation == 'dob'}" >
<input class="form-control" th:id="${item.name}" th:name="${item.name}" th:placeholder="${item.placeholder}" th:required="${item.required}"
th:type="${item.type}" th:attr="max=${#dates.format(#dates.createNow(), 'MM-dd-yyyy')}"/>
</div>
<div th:unless="${item.validation == 'dob'}" >
<input class="form-control" th:id="${item.name}" th:name="${item.name}" th:placeholder="${item.placeholder}" th:required="${item.required}"
th:type="${item.type}"/>
</div>
</div>
</div>
Advertisement.kt
class Advertisement(val media: ArrayList<MEDIA>? = null)
class Form(
val type:String="",
val required:Boolean,
val label:String="",
val placeholder:String="",
val name:String="",
val value:String="",
val validation:String="",
val min:Int,
)
As other answer suggested you can do it with javascript.
You can make use of this jQuery validation API
And add a custom validation method like so:
jQuery.validator.addMethod("olderThan21", function(value, element) {
return //age calculation logic if true-> validation pass
//if false->validation error }
, "You must be 21+ to subscribe");
In case that the validation isn't passed satisfactory this will prevent the form from submitting.

matTextareaAutosize overriding minimum row for Textarea

I have a textarea that I am trying to use matTextareaAutosize dynamically. I am using the buttons to change the showText value between true and false. However, it seems to be overriding the default rows being set with minRows. Now the default rows for the textarea is always 1. Is there a way assign default rows in a textarea with matTextareaAutosize being used?
Any help/suggestions would be much appreciated
textarea component.html
<mat-form-field>
<textarea matInput
class="descriptionText"
minRows="3"
[matTextareaAutosize]="showText"
#description
placeholder="{{ 'COLUMNS.description' | translate }}"
formControlName="description"
required>
</textarea>
<mat-error *ngIf="caseForm.invalid">{{ 'CASES.descriptionError' | translate }}</mat-error>
<mat-hint align="end">{{description.value.length}} / 1000</mat-hint>
</mat-form-field>
<div *ngIf="statusReason">
<button mat-button (click)="resizeDescription(true)">Show More</button>
<button mat-button (click)="resizeDescription(false)">Show Less</button>
</div>
component.ts
resizeDescription(value: boolean) {
this.showText = value;
}

JQuery Mobile filterable listview with multiple filters

I have a JQM 1.4.2 filterable listview which contain entries in different languages.
I would like to search only within items code, not the whole description, whereby i set the data-filtertext for list items to the item code, e.g. "Apple" or "Banana".
This works ok but now i need an additional language filter, e.g. "EN", "DE", and so on:
...
<li data-filtertext="Apple language_en">
<h2>Title</h2>
<p>Red fruit</p>
<p class="ui-li-aside"><strong>EN</strong></p>
</li>
...
...
<li data-filtertext="Banana language_de">
<h2>Titel</h2>
<p>Beschreibung</p>
<p class="ui-li-aside"><strong>DE</strong></p>
</li>
...
This is my data input:
<form class="ui-filterable">
<div class="ui-grid-a">
<div class="ui-block-a">
<input id="descriptions-input" data-type="search" placeholder="Search..." />
</div>
<div class="ui-block-b">
<fieldset data-role="controlgroup" data-type="horizontal">
<input name="lang-en" id="lang-en" type="checkbox" data-mini="true">
<label for="lang-en">EN</label>
<input name="lang-de" id="lang-de" type="checkbox" data-mini="true">
<label for="lang-de">DE</label>
<input name="lang-fr" id="lang-fr" type="checkbox" data-mini="true">
<label for="lang-fr">FR</label>
</fieldset>
</div>
</div>
</form>
What i try to do now, is that when a checkbox is selected, only the list items belonging to that language are visible.
How can i set this additional filter to my filterable jQuery Mobile listview?
Plunker: http://plnkr.co/edit/TV6rcatzdvaIvQzWBdoI?p=preview
EDIT:
This is the final solution, thanks to EZANKER: https://jsfiddle.net/m64kg5fw/4/
The filterable widget as a filterCallback property: http://api.jquerymobile.com/filterable/#option-filterCallback
You can use this to write a function that checks both the text and which language checkboxes are checked.
$(document).on("pagecreate", "#list-descriptions", function () {
$("#descriptions-list").filterable('option', 'filterCallback', checkedOrMatch);
$("#searchLangs input").on("change", function(){
$("#descriptions-list").filterable("refresh");
});
});
function checkedOrMatch(idx, searchValue) {
var ret = false;
var en = $("#lang-en").is(':checked');
var de = $("#lang-de").is(':checked');
var fr = $("#lang-fr").is(':checked');
var ignoreLang = false;
if (!en && !de && !fr) {
ignoreLang = true;
}
if (searchValue && searchValue.length > 0) {
searchValue = searchValue.toLowerCase();
var filttext = $(this).data("filtertext") || '';
filttext = filttext.toLowerCase();
if (filttext.indexOf(searchValue) < 0) {
ret = true; //filter this one out
} else if (!ignoreLang) {
//found filter text now check language
if ( (filttext.indexOf("language_en") > 0 && !en) || (filttext.indexOf("language_de") > 0 && !de) || (filttext.indexOf("language_fr") > 0 && !fr) ) {
ret = true; //filter this one out
}
}
}
return ret;
}
Updated DEMO
The checkedOrMatch functions runs for each item in the list. It first tests if the entered search text is found in the filter text. If it is, it then sees which language buttons are checked and tests the item for that language. I also added code to re-trigger the filter if the user selects language buttons after typing the search criteria.
NOTE: if the user types in "lang" you might not get what you want... In that case you could move the language designation out of the filter text and into a separate data-attribute.

Dynamic POST Radio Button

I create, dynamically, groups ou radio button in the "jQuery(document).ready(function())".
The partial code is:
(...) texto_html = texto_html + ""+record.descricao_equipamento+":"+record.nome_fornecedor+" ("+record.preco_equip_fornecedor+"€)";
(...)
The output is ok, one example:
<h5 class=""><strong>Transmissor 1:</strong></h5>
<div class="control-group">
<label class="control-label"></label>
<div class="controls">
<label class="radio line">
<input type="radio" name="optionsRadios11" value="11">Texto 1
</label>
</div>
</div>
<h5 class=""><strong>Transmissor 2:</strong></h5>
<div class="control-group">
<label class="control-label"></label>
<div class="controls">
<label class="radio line">
<input type="radio" name="optionsRadios12" value="120">
Texto 2
</label>
<label class="radio line">
<input type="radio" name="optionsRadios12" value="12">
Text 3
</label>
</div>
Now I want to POST my Form with AJAX (data: $("#myForm").serialize(),(..)
My problem is in my php file (that will retrieve the Posted values). How can I know how many radios groups I have? Is there a way to serialize them with, let's say an array of radios? Because really I just want their value, independently if they belong to group1 or group2 ou whatever.
thank you.
I'm stuck here! :)))
If I understood correctly you want to iterate over all the radios that were sent:
I can think of two ways of doing that:
You can iterate over all the $_POST values and filter them by a regex (to get just the "optionsRadiosXX" ones)
you can also append a new parameter in your http post (after form.serialize) with all the radios under a given form and then use this parameter as a guide in your php.
.
var getRadios = function() {
var map = {};
$("#formID input[type=radio]").each(function(){
var e = $(this);
if(!map[e.attr("name")]) {
map[e.attr("name")] = true;
}
});
var a = []
for(var r in map) {
a.push(r);
}
// alert(JSON.stringify(a));
return a;
}
See here an example: http://codepen.io/anon/pen/IKayC
Hope that helps.

jQuery Mobile: number input and plus/minus buttons inline

Is there a possibility to have a number input with minus-button on the left and plus-button on the right? Or maybe also -- ++ to change value in bigger steps.
I know that I'm not the first one asking this but:
This solution is not displaying correctly in the first turn and jQuery-Mobile-Stepper-Widget from Github (can't post another link because I'm new) does not work with current version of jQuery Mobile.
The result should look like the screenshot in this question: Has anyone implemented jQuery Mobile Add (+/-) Button Number Incrementers? respectively horizontal grouped buttons in jQuery Mobile
Any ideas or new snippets, working with current version of jQuery mobile?
Here is a hint, the rest is purely CSS job and extra JS codes to control the value, e.g. maximum, minimum...etc.
HTML
<div data-role="controlgroup" data-type="horizontal" data-mini="true">
<button id="plus" data-inline="true">+</button>
<input type="text" id="number" value="0" disabled="disabled" />
<button id="minus" data-inline="true">-</button>
</div>
Code
$('#plus').unbind('click').bind('click', function () {
var value = $('#number').val();
value++;
$('#number').val(value);
});
$('#minus').unbind('click').bind('click', function () {
var value = $('#number').val();
value--;
$('#number').val(value);
});
JSFiddle
In jQM the input type number does the most of the magic you want
<input type="number" name="number" value="0"/>
If you require more fancy styling you have to follow Omar's code
<i onclick="qty('plus');" class="fa fa-plus c_pointer"></i>
<input type="text" id="prdqty" name="qty" value="1" placeholder="1">
<i onclick="qty('minus');" class="fa fa-minus c_pointer"></i>
function qty(val){
pqty = $('#prdqty').val();
if (val == "plus") {
var newVal = parseFloat(pqty) + 1;
} else {
if (pqty > 1) {
var newVal = parseFloat(pqty) - 1;
} else {
newVal = 1;
}
}
$('#prdqty').val(newVal);
}

Resources