dropdown multiple options issue - html

I have a list of contacts, I would like to display the phoneNumbers in inputs with dropdown.
<div id="retrievedContactsDiv" data-bind="foreach: Model.userContacts.contacts()">
<!-- ko if: ($data.phoneNumbers().length >= 1) -->
<div class="control-group span3 offset3 ">
<div class="input-append btn-group">
<input id="appendedInputButton" type="text" data-bind="value:$data.phoneNumbers()[0].phoneNumber()">
<a class="btn btn-primary dropdown-toggle" data-toggle="dropdown" href="#">
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<!-- ko foreach: $data.phoneNumbers() -->
<li><span data-bind="text: $data.phoneNumber()"></span> </li>
<!-- /ko -->
</ul>
</div>
</div>
<!-- /ko -->
</div>
JS
$('.dropdown-menu li span').click(function(){
var elementVal=$(this).text();
$('#appendedInputButton').val('');
$('#appendedInputButton').val(elementVal);
});
My problem is that I can't have same id, if I use class all the phoneNumbers of my contacts list will be modified, How can I do it to display correct value if the user use dropdown ?
http://imageup.fr/uploads/1377867794.jpeg

Use jQuery smart selectors to find the closest common parent and then find the field inside it.
$('.dropdown-menu li span').click(function(){
var elementVal = $(this).text();
$(this).closest('.input-append').find('#appendedInputButton').val(elementVal);
});
Actually this is also wrong (in terms of HTML) because you're stuck with duplicate IDs. I would rather suggest you do the same with a class instead of id, it'll work exactly the same with the suggested JS above.

Related

How can I fix input width and label spacing to match surrounding lightning inputs

I have a LWC, there is a section which comprises of filters. Most of them are standard lightning-inputs, but two of them, are custom lookup components. The problem is, I can't find a way to make them align and look the same.. even if internally it is applying slds css classes (to some extent). This is how it's looking right now:
As you can see, every lightning input is aligned correctly, but then the two lookup component's inputs are wider and with less space between the label and the input.
This is the lookup html code:
<template>
<label if:true={label} class={getLabelClass} for="combobox">
<abbr if:true={required} title="required" class="slds-required">*</abbr>
{label}
</label>
<div class={getContainerClass}>
<div class={getDropdownClass} aria-expanded={hasResults} aria-haspopup="listbox" role="combobox">
<!-- Search input start -->
<div class={getComboboxClass} role="none">
<!-- Text input -->
<template if:false={useInput}>
<slot
aria-autocomplete="list"
aria-controls="listbox"
role="textbox"
id="combobox"
onchange={handleInput}
oninput={handleInput}
onkeydown={handleKeyDown}
onslotchange={handleSlotChange}
></slot>
</template>
<template if:true={useInput}>
<input onfocus={handleFocus}
onblur={handleBlur}
oninput={handleInput}
class="slds-input"
style="color: black;"/>
</template>
<template if:true={isLookup}>
<!-- Search icon -->
<lightning-icon
icon-name="utility:search"
size="x-small"
alternative-text="Search icon"
class={getSearchIconClass}
></lightning-icon>
<button
title="Remove selected option"
type="button"
onclick={handleClearSelection}
class={getClearSelectionButtonClass}
disabled={disabled}
>
<lightning-icon
icon-name="utility:close"
size="x-small"
alternative-text="Remove selected option"
class="slds-button__icon"
></lightning-icon>
</button>
</template>
</div>
<!-- Search input end -->
<!-- Result list box start -->
<div
id="listbox"
role="listbox"
>
<ul class={getListboxClass} role="presentation">
<!-- Spinner to display when waiting for results of search -->
<div if:true={loading}>
<lightning-spinner variant="brand" alternative-text="Loading" size="small"></lightning-spinner>
</div>
<template for:each={_searchResults} for:item="result">
<li data-id={result.id} onmousedown={handleResultClick} class="slds-listbox__item" key={result.id} role="presentation">
<div class="slds-media slds-listbox__option slds-listbox__option_plain slds-media_small" role="option">
<c-lookup-result template={_template} result={result}></c-lookup-result>
</div>
</li>
</template>
<!-- Result list end -->
<!-- No results start -->
<template if:false={hasResults}>
<li role="presentation">
<span class="slds-media slds-listbox__option_entity" role="option">
<span if:false={loading} class="slds-media__body">No results.</span>
<span if:true={loading} class="slds-media__body">Loading...</span>
</span>
</li>
</template>
<!-- No results end -->
</ul>
</div>
<!-- Result list box end -->
</div>
</div>
</template>
In my case, "useInput" is true
These are the getters:
get getContainerClass() {
let css = 'slds-combobox_container'; // slds-has-inline-listbox // sacado porque moleasta
if (this._hasFocus && this.hasResults) {
css += 'slds-has-input-focus ';
}
if (this.errors.length > 0) {
css += 'has-custom-error';
}
return css;
}
get getDropdownClass() {
let css = 'slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click ';
if (this._hasFocus && (this._currentConfig || this.loading)) {
css += 'slds-is-open';
}
return css;
}
get getComboboxClass() {
let css = 'slds-combobox__form-element slds-input-has-icon ';
return css += this.hasSelection() ? 'slds-input-has-icon_left-right' : 'slds-input-has-icon_right';
}
get getListboxClass() {
return (
'slds-listbox slds-listbox_vertical slds-dropdown slds-dropdown_fluid ' +
(this.scrollAfterNItems ? 'slds-dropdown_length-with-icon-' + this.scrollAfterNItems : '')
);
}
get getClearSelectionButtonClass() {
return (
'slds-button slds-button_icon slds-input__icon slds-input__icon_left ' +
(this.hasSelection() ? '' : 'slds-hide')
);
}
get getSearchIconClass() {
let css = 'slds-input__icon slds-input__icon_right ';
if (!this.isMultiEntry) {
css += this.hasSelection() ? 'slds-hide' : '';
}
return css;
}
get getLabelClass() {
return this.variant === VARIANT_LABEL_HIDDEN
? 'slds-form-element__label slds-assistive-text'
: 'slds-form-element__label';
}
get input() {
return this._input;
}
This is my code for what's on the image:
<template if:true={filters}>
<div class="slds-grid slds-gutters">
<div class="slds-col slds-size_1-of-2">
<c-lwc-filter filter={filters.Nombre} input-variant="label-inline"></c-lwc-filter>
<c-lwc-filter filter={filters.Codigo} input-variant="label-inline"></c-lwc-filter>
<c-lwc-filter filter={filters.CodigoFabricante} input-variant="label-inline"></c-lwc-filter>
</div>
<div class="slds-col slds-size_1-of-2">
<c-lwc-filter filter={filters.CodigoBarra} input-variant="label-inline"></c-lwc-filter>
<div class="slds-form-element slds-form-element_horizontal">
<c-lookup label="Familia" is-lookup=true use-input=true configs={configsFamilia} onremoveselection={removeSelection} data-name="_familiaId"></c-lookup>
</div>
<div class="slds-form-element slds-form-element_horizontal">
<c-lookup label="Marca" is-lookup=true use-input=true configs={configsMarca} onremoveselection={removeSelection} data-name="_marcaId"></c-lookup>
</div>
<c-lwc-filter filter={filters.Modelo} input-variant="label-inline"></c-lwc-filter>
</div>
</div>
</template>
(the lwcFilter components are lightning-inputs internally)
I got the label to be inline, wrapping my custom lookup lwc inside a div with slds-form-element_horizontal class. But the problem is, as the "input" inside the lookup is not just a normal input, it is wider and as I said before, the spacing between the label and said input is very small.
How can I make them look the same as the base lightning-inputs? And for it to work on every screen size? (because I tried using margin or padding but it doesn't look the same with smaller / bigger screens)
Any help would be appreciated!
Have you tried to include slds-form-element__control in getContainerClass()?
Something like this:
get getContainerClass() {
let css = 'slds-combobox_container slds-form-element__control'; // slds-has-inline-listbox // sacado porque moleasta
// ... rest of logic
return css;
}
Does it break anything?

How to hide element with AngularJS based on DOM element

I have an Umbraco setup. And when I edit in the CMS I would like for the "Preview" button to disappear whenever there is not a text-editor present in the DOM.
Angular file in localtion Umbraco/Views/content/edit.html
<form novalidate name="contentForm"
ng-controller="Umbraco.Editors.Content.EditController"
ng-show="loaded"
ng-submit="save()"
val-form-manager>
<umb-panel umb-tabs ng-class="{'editor-breadcrumb': ancestors && ancestors.length > 0}">
<umb-header tabs="content.tabs">
<div class="span7">
<umb-content-name placeholder="#placeholders_entername"
ng-model="content.name" />
</div>
<div class="span5">
<div class="btn-toolbar pull-right umb-btn-toolbar">
<div class="btn-group" ng-animate="'fade'" ng-show="formStatus">
<p class="btn btn-link umb-status-label">{{formStatus}}</p>
</div>
<umb-options-menu ng-show="currentNode"
current-node="currentNode"
current-section="{{currentSection}}">
</umb-options-menu>
</div>
</div>
</umb-header>
<umb-tab-view>
<umb-tab id="tab{{tab.id}}" rel="{{tab.id}}" ng-repeat="tab in content.tabs">
<div class="umb-pane">
<umb-property property="property"
ng-repeat="property in tab.properties">
<umb-editor model="property"></umb-editor>
</umb-property>
<div class="umb-tab-buttons" detect-fold ng-class="{'umb-dimmed': busy}">
<div class="btn-group" ng-show="listViewPath">
<a class="btn" href="#{{listViewPath}}">
<localize key="buttons_returnToList">Return to list</localize>
</a>
</div>
<div class="btn-group" ng-show="!isNew">
<a class="btn" ng-click="preview(content)">
<localize key="buttons_showPage">Preview page</localize>
</a>
</div>
<div class="btn-group dropup" ng-if="defaultButton">
<!-- primary button -->
<a class="btn btn-success" href="#" ng-click="performAction(defaultButton)" prevent-default>
<localize key="{{defaultButton.labelKey}}">{{defaultButton.labelKey}}</localize>
</a>
<a class="btn btn-success dropdown-toggle" data-toggle="dropdown" ng-if="subButtons.length > 0">
<span class="caret"></span>
</a>
Return to list
<!-- sub buttons -->
<ul class="dropdown-menu bottom-up" role="menu" aria-labelledby="dLabel" ng-if="subButtons.length > 0">
<li ng-repeat="btn in subButtons">
<a href="#" ng-click="performAction(btn)" prevent-default>
<localize key="{{btn.labelKey}}">{{btn.labelKey}}</localize>
</a>
</li>
</ul>
</div>
</div>
</div>
</umb-tab>
</umb-tab-view>
<ul class="umb-panel-footer-nav nav nav-pills" ng-if="ancestors && ancestors.length > 0">
<li ng-repeat="ancestor in ancestors">
{{ancestor.name}}
</li>
<li></li>
</ul>
</umb-panel>
</form>
I am not certain this is the correct file - but it seems to be the place where the Preview button is created.
The question now is. Can I somehow determine with angular if the text editor is active and then if it is, show the Preview button next to the Save and publish?
I would suggest the following
1) Determine what properties are accessible on the object that is passed through to the <umb-editor> directive.
Digging into the code I can see things like it has a .view property. You could inspect this at runtime in the browser console to see what additional properties are available
2) You can write a rule on the button to show if the collection of fields contains one with a certain property you might have identified
something like this...
Hope this helps
I found a second solution I might as well add here. I used the Umbraco Plugin Backoffice Tweaking.
Here I added this to my Config\BackofficeTweaking.config file
<?xml version="1.0" encoding="utf-8"?>
<Config>
<Rules>
<Rule Type="HideButtons" Enabled="true" Names="preview" Users="" UserTypes="" ContentTypes="Omraader,Grund,Udstykning,Indstillinger,Niveau,Oversigt_Mappe,Oversigt,Information_Mappe,Information,Afstande_Mappe,Afstande" Description="" />
</Rules>
<Scripts>
<Script Name="example"></Script>
</Scripts>
</Config>
Here you can also make some scripting or do many other things. The plugin also has a visual editor for Umbraco. Pretty easy to use.

angular7 building an navroute component but don't know what to do now

there is no issue with this code
to be more specific
can I create value's within my angular HTML or not?
I couldn't find anything about it so I think not and what do I do now if I want to create an automated menu.
i am using angular materials in this
I need to create a nav bar but I created it in angular HTML with some stuff in TS to create the data it needs to be automatic
so I need to loop this bottom part of my code with any value but I don't know how to start
<!-- need to loop this block of code whenever there is any new item with children -->
<div *ngFor="let childss of childs.children">
<div *ngIf="childss.children != null">
</div>
<a routerLink="/{{navRoute.path}}/{{childs.path}}/{{childss.path}}"><button mat-menu-item>{{childss.path}}</button></a>
</div>
</mat-menu>
</div>
<ng-template #elsesBlock>
<a routerLink="/{{navRoute.path}}/{{childs.path}}"><button mat-menu-item>{{childs.path}}</button></a>
</ng-template>
<!-- till here but have no idee how to do this effectively -->
childs is an item of an array
but it needs custom input data for the loop to function correctly but I have no idea how to do it if
<div class="nav_items" *ngFor="let navRoute of navRoutes">
<div *ngIf="navRoute.children != null; else elseBlock">
<div *ngIf="navRoute.children != null">
<a routerLink="/{{navRoute.path}}">
<button mat-button [matMenuTriggerFor]="menu">{{navRoute.path}}</button>
</a>
<mat-menu #menu="matMenu">
<div *ngFor="let childs of navRoute.children">
<div *ngIf="childs.children != null; else elsesBlock">
<a routerLink="/{{navRoute.path}}/{{childs.path}}">
<button mat-menu-item [matMenuTriggerFor]="child">{{childs.path}}</button>
</a>
<mat-menu #child="matMenu">
<!-- need to loop this blok of code when ever there is anny new item with children -->
<div *ngFor="let childss of childs.children">
<div *ngIf="childss.children != null">
</div>
<a routerLink="/{{navRoute.path}}/{{childs.path}}/{{childss.path}}"><button mat-menu-item>{{childss.path}}</button></a>
</div>
</mat-menu>
</div>
<ng-template #elsesBlock>
<a routerLink="/{{navRoute.path}}/{{childs.path}}"><button mat-menu-item>{{childs.path}}</button></a>
</ng-template>
<!-- till here but have no idee how to do this effectively -->
</div>
</mat-menu>
</div>
</div>
<ng-template #elseBlock>
<a routerLink="/{{navRoute.path}}">
<button mat-button>{{navRoute.path}}</button>
</a>
</ng-template>
</div>
this is my entire HTML
nav route is an array from my routes
I tried HTML link but that doesn't work with angular items
Try this syntax for your routerLink:
[routerLink]="['/' + navRoute.path + '/' + childs.path]"

Implementing Custom dropdown in Angular 2/4

I have been working on a custom dropdown functionality with a horizontal divider seperating two sets of values and have general select dropdown functionalities like using up and down arrow to navigate through the values, as well as go to specific values on press of a alphabet.
Code:
<div class="btn-group d-flex dropdown" dropdown>
<div class="floatLabelContainer w-100">
<button id="button-basic" dropdownToggle type="button" float-label [addLabel]="false" [hasFloat]="true" class="mb-2" aria-controls="dropdown-basic">
{{selectedCountry}}
<span class="caret" id="country-caret"></span>
</button>
<label for="button-basic" class="label-class" id="label-class">Country</label>
</div>
<ul id="dropdown-basic" slimScroll width="100%" height="250px" size="3px" alwaysVisible="true" wheelStep="20" *dropdownMenu
class="dropdown-menu d-block" role="menu" aria-labelledby="button-basic">
<li role="menuitem">
<a class="dropdown-item" tabindex="0" (click)="selectedCountry = country.name" *ngFor="let country of restOfCountries | orderBy : 'name'">{{country.name}}</a>
</li>
<li class="divider dropdown-divider"></li>
<li role="menuitem">
<a class="dropdown-item" tabindex="0" (click)="selectedCountry = country.name" *ngFor="let country of asianCountries | orderBy : 'name'">{{country.name}}</a>
</li>
</ul>
</div>
I have been able to achieve the divider part with the above code,
but is there away to implement arrows and alphabet press functionality also.
I would prefer to have angular specific implementation or a plugin, rather than js or jQuery
There is the possibility of evaluating keydown and keyup events:
https://alligator.io/angular/binding-keyup-keydown-events/
According to this you should be able to achieve this functionality by implementing click listeners such as:
<div class="btn-group d-flex dropdown"
(keydown.arrowup)="select(items[i-1])"
(keydown.arrowdown)="select(items[i+1])"
dropdown>
EDIT: so I tried this and turns out this does not work on any item on default. It works on inputs, how the example shows but I could not get i ti to work on a list by now.

Bootstrap collapse data-parent not working

I'm using bootstrap 2.2.1 and for whatever reason the data-parent attribute is not doing what is intended. It does not close a previous opened target when i click another target. Here's a fiddle with the code below, any ideas on how to fix this ?
<div id="accordion">
<ul>
<li>
<a href="#" data-toggle='collapse' data-target='#document', data-parent='#accordion'>option 1</a>
<ul id="document" class="collapse">
<li> suboption 1</li>
<li> suboption 1</li>
<li> suboption 1</li>
</ul>
</li>
<li>
option 2
</li>
<li>
option 3
</li>
<li>
<a href="#" data-toggle='collapse' data-target='#document2', data-parent='#accordion'>option 4</a>
<ul id="document2" class="collapse">
<li> suboption 1</li>
<li> suboption 1</li>
<li> suboption 1</li>
</ul>
</li>
</ul>
</div>
It says in the Bootstrap Documents:
If a selector is provided, then all collapsible elements under the
specified parent will be closed when this collapsible item is shown.
(similar to traditional accordion behavior - this is dependent on the
panel class)
so it has to be used with panel-groups, but you can override the javascript anyway.
http://getbootstrap.com/javascript/#collapse-options
I couldn't get this to work either - this may be something in the Bootstrap JS related to the fact that you are using lists rather than divs?
So to get it to work, I had to override the click event. Based on this question here: Collapsible accordion doesn't work inside a dropdpwn-menu Bootstrap
I added an accordion-toggle class to each option link, and then added the following JavaScript to get it to work:
$(document).on('click', '.accordion-toggle', function(event) {
event.stopPropagation();
var $this = $(this);
var parent = $this.data('parent');
var actives = parent && $(parent).find('.collapse.in');
// From bootstrap itself
if (actives && actives.length) {
hasData = actives.data('collapse');
//if (hasData && hasData.transitioning) return;
actives.collapse('hide');
}
var target = $this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, ''); //strip for ie7
$(target).collapse('toggle');
});​
This fiddle shows it in action.
've been struggling with bootstrap collapse as well. I was trying to something do something slightly different. I wanted inline toggle behavior. See my JS fiddle below. What I found is that bootstrap seems to require the existence of the "accordion-group" div in addition to the data-parent attribute covered in their docs. So either there is a bug in the JS or their docs do not include it. I also had to zero out the styles on the accordion-group div...
http://jsfiddle.net/cssguru/SRFFJ/
<div id="accordion2">
<div class="accordion-group" style="border:0;padding:0;margin:0">
<div id="collapseOne" class="collapse in">
Foo Bar...
<a data-toggle="collapse" data-parent="#accordion2" href="#collapseTwo">
Show Herp Derp
</a>
</div>
<div id="collapseTwo" class="collapse">
Herp Derp...
<a data-toggle="collapse" data-parent="#accordion2" href="#collapseOne">
Show Foo Bar
</a>
</div>
</div>
</div>
You have to use accordion-group class in your items, see issue https://github.com/twitter/bootstrap/issues/4988