Embed Lightning-input with lightning-icon in LWC - salesforce

Can someone help with sample of embedding the lightning-icon inside a lightning-input in LWC
<lightning-input type="search" name="To Address" label="To"
class="slds-input-has-icon_right slds-m-bottom_small">
<lightning-icon icon-name=action:email>
</lightning-icon>
</lightning-input>
I have also tried the below Approach which doesn't work
<div class="slds-form-element">
<label class="slds-form-element__label" for="text-input-id-1">Input Label</label>
<div class="slds-form-element__control slds-input-has-icon slds-input-has-icon_right">
<lightning-icon icon-name="utility:adduser" size="medium">
</lightning-icon>
<input type="text" id="text-input-id-1" class="slds-input" />
</div>

Here is the solution!!
<lightning-button-icon class="btnIconOverlay" icon-name="utility:adduser">
</lightning-button-icon>
<lightning-input type="search" name="To Address" value={toAddress}>
</lightning-input>
Add the below CSS to the lightning-button-icon, which assist in overlaying the icon.
.btnIconOverlay {
position: absolute;
z-index: 1;
margin: 0.5% 0 0 92%;
}

Related

#material-ui/core - How to set Textarea Value

Im new to this plugin and could not find any documentation regarding my question.
I want to simply apply a value to the textarea. I started by giving it an id, but there are multiple html components that make up this textarea, ad more that ons instance of the id I added.
The value I enter gets saved, but when I reopen the modal, its suppose to load the text that was saved for that specific area.
<TextField
className="bd_textarea"
id={ `tt_description_text outlined-multiline-static`}
label="Pain description"
multiline
rows={5}
onBlur={ (f)=>(this.textOnBlur({id:answeringPainSpot.spotId, value:f.target.value, doc_name:answeringPainSpot.doc_name})) }
/>
Here are my attempts on both class and id and none worked.
$(".bd_textarea").val(spot_text);
$(".bd_textarea").next().find('textarea').eq(0).val(spot_text);
$('.bd_textarea').find('textarea').val(spot_text);
$("#tt_description_text").val(spot_text);
$("#tt_description_text").next().find('textarea').eq(0).val(spot_text);
$('#tt_description_text').find('textarea').val(spot_text);
This is the code when renderd.
<p class="MuiTypography-root MuiTypography-body1" id="modal-modal-description" sx="[object Object]">
<div class="MuiFormControl-root MuiTextField-root bd_textarea">
<label class="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated" data-shrink="false" for="tt_description_text outlined-multiline-static" id="tt_description_text outlined-multiline-static-label">Pain description</label>
<div class="MuiInputBase-root MuiInput-root MuiInput-underline MuiInputBase-formControl MuiInput-formControl MuiInputBase-multiline MuiInput-multiline">
<textarea aria-invalid="false" id="tt_description_text outlined-multiline-static" rows="5" class="MuiInputBase-input MuiInput-input MuiInputBase-inputMultiline MuiInput-inputMultiline"></textarea>
</div>
</div>
</p>
Can you try setting the value like this:
<textarea
className="form-control"
rows="4"
placeholder="Add a comment"
value={this.state.newComment}
onChange={(e) => {
this.setState({
newComment: e.target.value,
);
}}>
</textarea>

Why does Cypress not recognise the testid of a react-datepicker element?

Target
To make Cypress recognise and manipulate a DatePicker element.
Problem
I cannot make Cypress recognise the data-testid of a DatePicker element, and so have no way of testing it E2E.
Error
Timed out retrying: Expected to find element: [data-testid="edit_dob"], but never found it.
Attempts
I have tried placing the DatePicker element inside input and div elements to target instead, but they fail as expected for other reasons.
I have also looked through the docs for both DatePicker and Cypress for mention of the other, and for similar questions here.
Code
The code below works as expected, it's just Cypress that seems to be incompatible with the DatePicker input.
function displayEditDetails() {
let listOfForms = [];
for (const detail in details) {
listOfForms.push(
<FormGroup controlId={detail} key={`key_edit_${detail}`}>
<FormLabel>{detail.charAt(0).toUpperCase() + detail.slice(1).replace('_', ' ')}</FormLabel>
<FormControl
data-testid={`edit_${detail}`}
type={detail}
value={details[detail] || ''}
onChange={handleDetailsChange}
/>
</FormGroup>
)
}
listOfForms.push(
<DatePicker
data-testid={'edit_dob'}
selected={dob}
onChange={setDob}
maxDate={new Date()}
/>
);
return(
listOfForms
)
}
Test
it('Displays the edit fields', () => {
cy.get('[data-testid="accountButton"]')
.click();
cy.get('[data-testid="editUserDetailsButton"]')
.click();
cy.get('[data-testid="user_email"]')
.should('not.be.visible');
cy.get('[data-testid="edit_full_name"]')
.should('be.visible');
cy.get('[data-testid="edit_dob"]')
.should('be.visible');
cy.get('[data-testid="edit_email"]')
.should('be.visible')
.should('have.value', 'test#editdetails.com');
})
Once I can target it, I plan to test clearing the current input and typing a new date in. Any help targeting the picker and warnings of further potential pitfalls are appreciated.
Edit: Here's the generated HTML of the form.
<form>
<div class="form-group">
<label class="form-label" for="email">Email</label>
<input data-testid="edit_email" type="email" id="email" class="form-control" value="admin#example.com" style="background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHklEQVQ4EaVTO26DQBD1ohQWaS2lg9JybZ+AK7hNwx2oIoVf4UPQ0Lj1FdKktevIpel8AKNUkDcWMxpgSaIEaTVv3sx7uztiTdu2s/98DywOw3Dued4Who/M2aIx5lZV1aEsy0+qiwHELyi+Ytl0PQ69SxAxkWIA4RMRTdNsKE59juMcuZd6xIAFeZ6fGCdJ8kY4y7KAuTRNGd7jyEBXsdOPE3a0QGPsniOnnYMO67LgSQN9T41F2QGrQRRFCwyzoIF2qyBuKKbcOgPXdVeY9rMWgNsjf9ccYesJhk3f5dYT1HX9gR0LLQR30TnjkUEcx2uIuS4RnI+aj6sJR0AM8AaumPaM/rRehyWhXqbFAA9kh3/8/NvHxAYGAsZ/il8IalkCLBfNVAAAAABJRU5ErkJggg=="); background-repeat: no-repeat; background-attachment: scroll; background-size: 16px 18px; background-position: 98% 50%; cursor: auto;">
</div>
<div class="form-group">
<label class="form-label" for="full_name">Full name</label>
<input data-testid="edit_full_name" type="full_name" id="full_name" class="form-control" value="Jareth">
</div>
<div class="form-group">
<label class="form-label" for="address">Address</label>
<input data-testid="edit_address" type="address" id="address" class="form-control" value="">
</div>
<div class="form-group">
<label class="form-label" for="postcode">Postcode</label>
<input data-testid="edit_postcode" type="postcode" id="postcode" class="form-control" value="">
</div>
<div data-testid="edit_dob">
<div class="react-datepicker-wrapper">
<div class="react-datepicker__input-container">
<input type="text" class="" value="04/03/1999">
</div>
</div>
</div>
<button data-testid="confirmChangesButton" type="submit" class="LoaderButton btn btn-primary btn-block">Confirm Changes</button></form>
The problem is visible when looking at the HTML generated by running the app.
DatePicker HTML
<div data-testid="edit_dob">
<div class="react-datepicker-wrapper">
<div class="react-datepicker__input-container">
<input type="text" class="" value="04/03/1999">
</div>
</div>
</div>
The DatePicker is rendered as an input element inside a few divs, and the test id doesn't target the input.
Solution
The Selector Playground API for Cypress suggests cy.get('.react-datepicker__input-container > input'), the class of the parent div of the input. With this I can target the DatePicker, clear it, and type new input.
Notes For Next Time
Examine the HTML
Read the Docs more thoroughly
Reference the concepts used in the cy.pickDateRange command in the Cypress Real World App. It is a payment application to demonstrate real-world usage of Cypress testing methods, patterns, and workflows.
In the code for the command, you will find it is necessary to examine the HTML produced and traverse it appropriately for your needs.

Use Bootstrap "prepend" with react-select

I'm trying to use the Bootstrap input-group-prepend with react-select, however react-selects' styling doesn't seem to be the current bootstrap/reactstrap and so doesn't want to work together.
The select box doesn't merge with the prepend element (radius 4px on all corners instead of just right corners), also the box shadow on the element is totally different to what bootstrap 4 uses, this creates an annoying consistency issue.
This gives the desired look and feel, and stays the same when using .map for the options.
<InputGroup className="mb-3">
<InputGroupAddon addonType="prepend">
<InputGroupText><FaBriefcaseMedical /></InputGroupText>
</InputGroupAddon>
<Input type="select" name="select" id="ConsultantSelect">
<option value="" value disabled selected>Select Consultant</option>
<option>Roland Deschain</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</Input>
</InputGroup>
This however is using react-select doesn't display as expected/desired
<InputGroup className="mb-3">
<InputGroupAddon addonType="prepend">
<InputGroupText><FaHSquare /></InputGroupText>
</InputGroupAddon>
<Select
options={this.state.hospitals}
name={this.state.hospitals}
/>
</div>
Iconography is important for what I'm doing due to the target audience.
EDIT:
a janky work around is to give the react-select className="form-control" and then then style it to match Bootstrap4.
<InputGroup className="mb-3">
<InputGroupAddon addonType="prepend">
<InputGroupText><FaHSquare /></InputGroupText>
</InputGroupAddon>
<Select className="form-control"
options={this.state.hospitals}
name={this.state.hospitals}
/>
</InputGroup>
.css-2b097c-container {
padding: 0px;
}
.css-yk16xz-control {
background-color: #ffffff00 !important;
border-style: none !important;
}
.css-1pahdxg-control {
border-color: #80bdff !important;
box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25) !important;
border-top-left-radius: 0 !important;
border-bottom-left-radius: 0 !important;
}
But this is clearly not a ideal solution.
The CCS changes result in the below, which now has the drop down appearing the same as a normal select input, and also matches the other inputs such as the text inputs.
What worked for me was to wrap the Select in a div with the class "form-control". It also needs a zero padding.
<div className="react-select form-control p-0">
<Select />
</div>
The first div inside Select also needs a -1px margin.
.react-select > div {
margin: -1px;
}
I have the same use case as you. Only I've been wrapping Select in a div with a % width style defined.
However, this has to be set for a screen size. It will cause the right side to be misaligned if the % is too small, or will create a new line if the % is too large.
<InputGroup className='mt-1'>
<InputGroupAddon addonType="prepend">
<InputGroupText>Select</InputGroupText>
</InputGroupAddon>
<div style={{width: '80%'}}>
<Select isMulti name='subjects'
options={optionsArray}
placeholder="Click or type"
/>
</div>
</InputGroup>

Angular validation issue

I've got an issue with the Angular validation classes. I've got three classes in my css with three different images, that shows if the field is required, if the user has filled in correct or not. E.g. I have one input field where the user types in a personal number, and I look it up in a service and fills the model with firstname, lastname, address etc. which also populates the input fields.
I made a simple example
HTML
<div ng-app="ebu" ng-controller="search">
<button id="search-apparentice" ng-click="addName()">Search apprentice</button>
<hr>
<input id="username" type="text" ng-model="user.name" required>
</div>
JS
angular.module('ebu', []).
controller('search', function($scope) {
$scope.user = {};
$scope.addName = function()
{
$scope.user.name = "Kasper";
}
})
CSS
input[required].ng-invalid
{
border: 1px solid red;
}
input[required].ng-valid
{
border: 1px solid green;
}
input[required].ng-pristine
{
border: 1px solid blue;
}
[FiddleJS][1][1]: http://jsfiddle.net/kaspergantzhorn/z1wg6tko/9/
It's still pristine because pristine means it has never had focus. The user is not clicking on it, therefore it never gets dirty. If this isn't a user-modified field, pristine is not the right thing to use.
Additionally, in the ng-change of the input, you should be able to use $setDirty.
<input type="text" ng-change="formName.inputName.$setDirty()" />
For you code above:
<div ng-app="ebu" ng-controller="search">
<button id="search-apparentice" ng-click="addName(); myForm.name.$setDirty()">Search apprentice</button>
<hr>
<form name="myForm">
<input name="name" id="username" type="text" ng-model="user.name" required>
</form>
</div>

IE7 float (not div's)

I wanted to make simple form, without awesome div's and CSS - it structure is like:
<form id="cform" action="/" method="post">
<fieldset>
<label class="first" for="name">Nazwa firmy: </label><input id="name" name="name" type="text" />
<label class="first" for="email">Email: </label><input id="email" name="email" type="text" />
</fieldset>
</form>
CSS
#cform input, #cform textarea, #cform label, #cform select
{
float: left;
}
label.first, #cform input[type="submit"]
{
margin-bottom: 10px;
width: 150px;
float: left;
clear: both;
}
#cform textarea
{
width: 400px;
height: 250px;
margin-bottom: 10px;
}
In FF, IE8, Chrome and Opera it looks good. But in IE7 inputs are looking, like they don't have float at all. How to fix it? (version without adding divs please)
Aww, forgot link
http://site.amm.siedlce.pl/front/page/get/79/
IE7 doesn't support the attribute selector, input[type="submit"].
Reference them by class.

Resources