Angular5 Autocomplete search from array - autocomplete

I am building a filter for finding city`s.
I have an array with citynames. (this.place = [Londen, Amsterdam, Rome, Paris])
I have an inputfield when a user types a letter in the inputfield I want to search through the array and give him a list of suggestions.
I tried this but it does not work:
Html:
<input #inputValue (keyup)="filterValues($event)" />
<div *ngIf='placesFound'>
<span *ngFor="let place of placesFound">
{{place}}
</span>
</div>
TS file:
filterValues(event) {
let key = event.key
this.placesFound = this.places.filter(function(event) {
return this.places.indexOf(key) > -1
})
}
this does not work does someone has any suggestions?
thx!

Related

How to get attribute value in <a> element?

How can i take the value of the data-set attribute or change it in the link with the following structure:
<a href='#' data-set='22'>Text</a>
I know that in jquery I can use the:
$('a').attr ('data-set');
And to change your content:
$('a').attr ('data-set', '01');
But in Ionic4 i am not getting it, already researched and can not exactly that.
Can anyone help me?
In native JavaScript you can just do
To get the attribute use document.querySelector('a').getAttribute('data-set');
And to set the attribute use document.querySelector('a').setAttribute('data-set', '01');
You can use HTMLElement.dataset
assuming you have <a href='#' id="mylink" data-set='22'>Text</a>
let elem = document.querySelector('#mylink');
//get
el.dataset.set
//set
el.dataset.set = "01"
Note: HTMLElement.dataset may not be supported in some browsers, please test it before put it into production
SOLVED:
I did it this way:
<ion-input #myInput data-set="01"></ion-input>
#ViewChild ('myInput', { read: ElementRef }) myInput: ElementRef;
ngAfterContentInit() {
console.log(this.myInput.nativeElement.dataset.dta1);
}
in HTML file,
<ul>
<li #messageEl *ngFor="let message of messages" [attr.data-message-id]="message.id">
{{ message.text }}
<br><button (click)="logMessageId(messageEl)">Console Log </button>
</li>
</ul>
in .ts file,
logMessageId(el){
let messageId = el.getAttribute('data-message-id');
//let messageId = el.dataset.messageId;
console.log("Message Id: ", messageId);
}

angular 2, validate form if at least one input is typed

I'm quite new to Angular, and I've already searched the web, without finding a correct solution for my situation.
I have a dynamic form created by a *ngFor. I need to disabled the submit button if the inputs are all empty and show the alert div; but I need to enable the submit if at least one of those forms contains something different from ''.
Here is my html code
<form class="form-inline" #form="ngForm">
<div class="form-group" *ngFor="let meta of state.metaById; let i = index" style="margin: 5px">
<label>{{meta.nome}}</label>
<input type="text" class="form-control" #nome (blur)="inputInArray(nome.value, i);">
</div>
<button type="button" class="btn btn-primary" (click)="getCustomUnitaDocumentaliRow(this.param)" [disabled]="fieldNotCompiled">invia</button>
</form>
<div class="alert-notification" [hidden]="!fieldNotCompiled">
<div class="alert alert-danger">
<strong>Va compilato almeno un campo.</strong>
</div>
</div>
and here is my Typescript code
inputInArray(nome: string, indice) {
if (this.state.controlloMetaId = true) {
this.state.metadatoForm[indice] = nome;
}
// this.fieldNotCompiled = false;
for (const i in this.state.metaById) {
console.log(this.state.metadatoForm);
if (isUndefined(this.state.metadatoForm[i]) || this.state.metadatoForm[i] === '') {
this.fieldNotCompiled = true && this.fieldNotCompiled;
} else {
this.fieldNotCompiled = false && this.fieldNotCompiled;
}
console.log(this.fieldNotCompiled);
}
With this code I can check the first time a user type something in one input, but it fails if it empty one of them (or all of them)
Thanks for your time
UPDATE
Check if any input got a change that is different from empty or space, just by doing:
<input ... #nome (input)="fieldNotCompiled = !nome.value.trim()" ....>
DEMO
You can set a listener to the form changes:
#ViewChild('form') myForm: NgForm;
....
ngOnInit() {
this.myForm.valueChanges.subscribe((value: any) => {
console.log("One of the inputs has changed");
});
}

Make form dynamicly add input with number

can anyone make these functions simple?
i have a ul:
<ul class="phone-type">
<li class="office" id="1"></li>
<li class="mobile" id="2"></li>
<li class="fax" id="3"></li>
</ul>
and the JS :
var o = 0;var m = 0;var f = 0;
$('ul.phone-type li.office').click(function () {
o++;
$('.phones').append('<input class="form-control phone_type" placeholder="'+ $(this).text()+'-'+o+'" name="phone['+$(this).attr('class')+'-'+o+']" type="text" ><br>');
});
$('ul.phone-type li.mobile').click(function () {
m++;
$('.phones').append('<input class="form-control phone_type" placeholder="'+ $(this).text()+'-'+m+'" name="phone['+$(this).attr('class')+'-'+m+']" type="text" ><br>');
});
$('ul.phone-type li.fax').click(function () {
f++;
$('.phones').append('<input class="form-control phone_type" placeholder="'+ $(this).text()+'-'+f+'" name="phone['+$(this).attr('class')+'-'+f+']" type="text" ><br>');
});
i have to reset it for every li..
is there any way that i can make it simple!!!!
tnx
This method will allow for an indefinite number of clickable list elements. Just ensure that you provide the 'data-type' attribute in any elements that are included.
When storing data in an html element, it is usually best to use the 'data' attribute. Using classes only works when there is one class.
HTML
<ul class="phone-type">
<li data-type="office" id="1">office</li>
<li data-type="mobile" id="2">mobile</li>
<li data-type="fax" id="3">fax</li>
</ul>
<div class="phones"></div>
JS
// This object will contain how many clicks each element has
var typeClicks = {};
$('ul.phone-type li').click(function() {
var li = $(this),
type = li.data('type'),
text = li.text(),
clicks;
// check if typeClicks contains any click data for this element
if (typeClicks.hasOwnProperty(type)) {
// if it does, increases tracked clicks by one
typeClicks[type]++;
clicks = typeClicks[type];
} else {
// if not, this will create an entry for this element
clicks = typeClicks[type] = 1;
}
// if not, this will create an entry for this element
$('.phones').append('<input class="form-control phone_type" placeholder="'+text+'-'+clicks+'" name="phone['+type+'-'+clicks+']" type="text" ><br>');
});

Show tags under their own specific tab

I'm creating a tag system on my website. So far it's all working great. But now I wish to create a page that shows all my tags under their own tab like you have with a portfolio page.
Example: http://www.don-zalmrol.be/tags?tag=Electronics
My page already displays the tags for a specific tag under it's own tab (i.e. electronics), but as you might guess I wish to populate the other tags in their respective tab as well.
So in short you land a view that displays the tag you've selected, but on the same page you can see the others as well.
Anybody has any idea how I can do this? I don't think I'm far away from the solution as I can already load the projects for specific tags under it's own tab. Now I only need to populate the remaining tabs with the tags!
Thanks!
This is my code so far:
http://pastebin.com/jwGW0NKZ
#inherits Umbraco.Web.Mvc.UmbracoTemplatePage
#inherits Umbraco.Web.Mvc.UmbracoTemplatePage
#{
var portfolio = Umbraco.TagQuery.GetAllContentTags().OrderBy(t => t.Text);
var tagList = Umbraco.TagQuery.GetAllContentTags().OrderBy(t => t.Text);
string tag = Request.QueryString["tag"];
if (!tag.IsNullOrWhiteSpace())
{
var publishedContent = Umbraco.TagQuery.GetContentByTag(tag);
if (publishedContent.Count() > 0)
{
#* Show title *#
<div class="media contact-info wow fadeInDown" data-wow-duration="1000ms" data-wow-delay="600ms">
<center>
<div>
<i class="fa fa-tags"></i>
</div>
<br />
<div class="media-body">
<h2>Tags</h2>
<p>Browse content by tag</p>
</div>
</center>
<br />
</div>
#* Show tag titles in tabs *#
<ul class="portfolio-filter text-center">
<li><a class="btn btn-default" href="#" data-filter="*">All tags</a></li>
#foreach (var tags in tagList)
{
<!-- Create a selected tag -->
if(#tags.Text == #tag)
{
<li><a class="btn btn-default active" href="#" data-filter=".#tag">#tag</a></li>
}
#* Show all other tags *#
else
{
<li><a class="btn btn-default" href="#" data-filter=".#tags.Text">#tags.Text</a></li>
}
}
</ul>
<div class="row">
<div class="portfolio-items">
#* Start picture content *#
#foreach (var tags in tagList)
{
#* Put selected tag in the right tag tab *#
if(#tags.Text == #tag)
{
#* Show tag content *#
foreach (var item in publishedContent.OrderByDescending(i => i.CreateDate))
{
<div class='portfolio-item #tag col-xs-12 col-sm-4 col-md-3'>
<div class="recent-work-wrap">
#* IF the project has a picture *#
#if(item.HasValue("pictureOfTheProject"))
{
var featureImage = Umbraco.TypedMedia((int)item.GetPropertyValue("pictureOfTheProject"));
<img class="img-responsive" src="#featureImage.GetCropUrl(250, 250)" alt='#item.GetPropertyValue("titleOfTheProject")' />
<div class="overlay">
<div class="recent-work-inner">
<h3>#item.GetPropertyValue("titleOfTheProject")</h3>
<a class="preview" href="#featureImage.GetCropUrl(250, 250)" rel="prettyPhoto">
<i class="fa fa-eye"></i> View
</a>
</div>
</div>
}
#* Else when the project doesnt have a picture, show default one *#
else
{
var noImage = "http://www.don-zalmrol.be/media/1440/no_image_available.png";
<img class="img-responsive" src="#noImage.GetCropUrl(250, 250)" alt="No image" />
<div class="overlay">
<div class="recent-work-inner">
<h3>#item.GetPropertyValue("titleOfTheProject")</h3>
<a class="preview" href="#noImage.GetCropUrl(250, 250)" rel="prettyPhoto">
<i class="fa fa-eye"></i> View
</a>
</div>
</div>
}
</div>
</div>
}
}
#* Put the other tags under there own tab *#
else
{
}
}
#* End dynamic tags *#
</div>
</div>
}
#* No content matching the tag? *#
else
{
<p>There isn't any content matching that tag.</p>
#Html.Partial("TagList")
}
}
#* Show the tag list with amount *#
else
{
#Html.Partial("TagList")
}
}
EDIT 27-03-2016
Ok so I now know that I need to play around with my tag query or use the IEnumerable. But I can't seem to find it out how I can do this without breaking the code...
#* Get all tags and order them by name *#
var tagList = Umbraco.TagQuery.GetAllContentTags().OrderBy(t => t.Text);
#* Get requested tag *#
string tag = Request.QueryString["tag"];
#* Show all content by requested tag *#
var publishedContent = Umbraco.TagQuery.GetContentByTag(tag);
Above are the pieces of code that list all the tags I have in a var, gets the name from the URL (i.e. Electronics) and one that then displays all content that matches said queried tag.
So in short I need to change the last part of the TagQuery to list all content that has a tag and then filter it out by the querystring to display them in their own category.
But how can list all tagcontent?
Cheers,
Don
Your issue is on line 76 of the pastebin where you loop through the published content, which is already filtered by the selected tag. Because of this, only content with the selected tag ever gets written to the template.
What you need to do is use the loop on line 70 where you're looping through all tags. The jQuery plugin you're using will handle the filtering by using the CSS class you add on line 78. You can get rid of the loop on line 76.
For clarity, I would also change the
#foreach (var tags in tagList)
to
#foreach (var item in tagList)
since the foreach is producing a single tag rather than plural "tags" as your code insinuates. This has the added bonus of allowing you to keep the rest of your code the same once you remove the loop on line 76.

Selecting a DOM Element when (auto-generated) HTML is not well formed

I'm trying to select a control in order to manipulate it but I'm having a problem: I can't select it. Maybe it's because the xml structure, but I really can't change it because it is externally created. SO I have this:
<span class="xforms-value xforms-control xforms-input xforms-appearance xforms-optional xforms-enabled xforms-readonly xforms-valid " id="pName">
<span class="focus"> </span>
<label class="xforms-label" id="xsltforms-mainform-label-2_2_4_3_">Name:</label>
<span class="value">
<input readonly="" class="xforms-value" type="text">
</span>
<span class="xforms-required-icon">*</span>
<span class="xforms-alert">
<span class="xforms-alert-icon"> </span>
</span>
</span>
And what I need is to get the input (line 5). I tryed a lot, for example:
var elem01 = document.getElementById("pName");
console.log("getElementById: " + elem01);
var elem02 = document.evaluate(".//*[#id='pName']" ,document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null );
console.log("evaluate: " + elem02);
console.log(elem02.singleNodeValue);
var elem03 = document.querySelector("#pName");
console.log("querySelector: " + elem03);
But none of that allows me to get a reference to the control. What's wrong?
With XPath, the problem seems to be the XML is no well formed, so document.getElementById("pName") doesnt return anything.
http://jsfiddle.net/wmzyqqja/7/
The problem with your example is that you are executing your Javascript before the relevant DOM elements are loaded (i.e. your code is in the head element):
This will fix the example:
window.onload = changeControlValue;
JSFiddle: http://jsfiddle.net/TrueBlueAussie/wmzyqqja/8/
Try this
var elem01 = document.getElementById("pName");
var inp = elem01.getElementsByTagName("input")[0];
(in JSFiddle the "onload" setting is required.)