Auto fill an image template with react? - reactjs

I'm currently using react to create a student portal. A functionality that we want to add is to have customized awards for students when they complete a certain milestone. Something like this https://www.pinterest.com/pin/460563499365843175/. We have our own template that we want to follow, where I need to fill in the student's name and achievement, which is obviously different for everyone. Is there any component/api I can use to do this through react? I'm open to all ideas and suggestions. Thanks!

If I understand you correctly, you will want to create a custom component per award type, with images, boiler-plate text and input fields. You can pass in to these components the props you will need e.g. Name, Date etc. You can then render this component only when necessary, passing in the individual student's details, to presented in the input fields. You can use CSS to style the component however you'd like, e.g. removing top/left/right borders around fields etc.
There are no bespoke components like this I'm aware of, but it wouldn't be too difficult to create one yourself.
const Award = ({type, name}) => (
<div class="award">
<div class="header">Award of Excellence</div>
<div class="type">
<label htmlFor="type">for</label>
<input type="text" id="type" name="type" value={type} />
</div>
<div class="recipient">
<label htmlFor="recipient">Awarded to</label>
<input type="text" id="recipient" name="recipient" value={name} />
</div>
<div class="footer">
<div>
<input type="text" id="date" name="date" value={new Date()} />
<label htmlFor="date">Date</label>
</div>
<img class="medal" src="https://www.diggerland.com/wp-content/uploads/2015/01/Gold-medal1.png" alt="medal" />
<div>
<input type="text" id="signature" name="signature" value="Professor Plum" />
<label htmlFor="signature">Signature</label>
</div>
</div>
</div>
);
ReactDOM.render(<Award type="1st Award" name="John Smith" />, document.body);
.award {
display: flex;
flex-direction: column;
align-items: center;
}
.type, .recipient, .footer > * {
display: flex;
flex-direction: column;
align-items: center;
padding: 1rem;
font-family: "luminary";
}
.footer {
display: flex;
padding: 2rem;
}
.medal {
height: 4rem;
}
input {
border-width: 0 0 0.1rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

Related

How to check the Radio Button in Cypress. The regular check() is not working

I bumped into a problem with Cypress. I just couldn't check the radio button.
I have 7 questions with Yes or No radio buttons. By default, all buttons are checked to "NO". I need to check the "YES" options, it will send an API call to the backend and continue to do magic.
The html code for YES looks like this:
<input type="radio" id="options[0]radiovalue-true" class="form-control is-action-field form-check-input" value="true" style="opacity: 0; cursor: pointer; height: 0px; width: 0px;">
The html code for NO looks like this:
<input type="radio" id="options[0]radiovalue-false" class="form-control is-action-field form-check-input" value="false" checked="" style="opacity: 0; cursor: pointer; height: 0px; width: 0px;">
By default the NO radio button has property: checked: true , the YES radio button has property: checked: false
This is my tries:
cy.get('[class="sc-fzoJMP"]')
.find('.list-group-item')
.then((item) => {
cy.wrap(item)
.eq(0)
.should('contain', 'Is this opportunity?')
.find('input[type="radio"]')
.then((radioButtons) => {
cy.wrap(radioButtons).eq(0).check({ force: true }).should('be.checked');
});
I used different locators, tried ('[type="radio"]'), (':radio'), ('#options[0]radiovalue-true') I used different check methods: cy.get(':radio').click({force: true}) , cy.get(':radio').check('true', {force: true}) and tried to move code with checking radio buttons out of the loop but this is something else. It doesn't check the radio button but can verify that it's not checked.
I found one solution to use invoke property:
cy.wrap(radioButtons).eq(0).invoke('prop', 'checked', true).should('be.checked');
cy.wrap(radioButtons).eq(1).invoke('prop', 'checked', false).should('not.be.checked');
But it's checking "YES" radio button but it's not unchecking "NO" radio button and it doesn't send API call to the backend as supposed to do.
This is full HTML code for YES and NO radio buttons:
<div class="d-flex ">
<div class="mr-4" style="position: relative;">
<div class="form-check">
<input type="radio" id="options[0]radiovalue-true" class="form-control is-action-field form-check-input" value="true" style="opacity: 0; cursor: pointer; height: 0px; width: 0px;">
<label for="options[0]radiovalue-true" class="ml-0 form-check__radio form-check-label">
<svg viewBox="0 0 24 24" style="height: 20px; min-height: 20px; width: 20px; min-width: 20px; opacity: 1;">
<title>Select Option</title>
<circle cx="12" cy="12" r="9" stroke="#666666" stroke-width="2" fill="white"></circle>
</svg>
<p class="sc-fznyAO hdDwJr ml-1 typography-body ">Yes</p>
</label>
</div>
</div>
<div class="mr-4" style="position: relative;">
<div class="form-check">
<input type="radio" id="options[0]radiovalue-false" class="form-control is-action-field form-check-input" value="false" checked="" style="opacity: 0; cursor: pointer; height: 0px; width: 0px;">
<label for="options[0]radiovalue-false" class="ml-0 form-check__radio form-check-label">
<svg viewBox="0 0 24 24" style="height: 20px; min-height: 20px; width: 20px; min-width: 20px; opacity: 1;">
<title>Selected Option</title>
<circle cx="12" cy="12" r="9" stroke="var(--dcp-color-primary)" stroke-width="2" fill="none"></circle>
<circle cx="12" cy="12" r="5" fill="var(--dcp-color-primary)"></circle>
</svg>
<p class="sc-fznyAO hdDwJr ml-1 typography-body ">No</p>
</label>
</div>
<div class="action-field-wrapper is-action-field"></div>
</div>
</div>
The id's that have been assigned contain characters that don't work with # notation, but you can use attribute notation
cy.get('.list-group-item')
.eq(0)
.find('[id="options[0]radiovalue-true"]') // query id as an attribute
.click()
cy.get('.list-group-item')
.eq(0)
.find('[id="options[0]radiovalue-false"]')
.click()
Specifically, the [] in the ids stops '#options[0]radiovalue-true' from working.
With the expanded fragment, this works
cy.get('input[id="options[0]radiovalue-true"]')
.click({force:true})
.should('be.checked')
You need force:true because of the style opacity:0 and width & height 0.
This means the input is effectively hidden, and there is probably a better way to test this - perhaps clicking on the SVG icons.
You can use the IDs and click to select the 'Yes' or 'No' radio buttons.
cy.get('.list-group-item')
.eq(0)
.find('#options[0]radiovalue-true')
.click() //Clicks Yes
cy.get('.list-group-item')
.eq(0)
.find('#options[0]radiovalue-false')
.click() //Clicks No

React-Icons: Icon not aligning with Text

I am using react-icons in one of my projects and I am not able to align the icons (vertically) with the text. Following is what I am getting currently.
As you can see -- The icons are a little higher than the text.
Following is my HTML code:
<div className="route-info-container">
<div>
<p>Difficulty (1-10)</p>
<h2><AiFillFire />{route.difficulty}</h2>
</div>
<div>
<p>Length</p>
<h2><GiTrail />{route.length}</h2>
</div>
<div>
<p>Est Driving Time</p>
<h2><RiTimerFlashFill />{route.estimatedDrivingTime}</h2>
</div>
<div>
<p>Permits</p>
<h2><IoNewspaperSharp />{route.permits? 'Required': 'Not Required'}</h2>
</div>
</div>
Following is my css:
.route-info-container {
display: grid;
grid-template-columns: auto auto;
}
.route-info-container h2 {
font-size: 25px;
margin-top: 10px;
}
It' s because the svg' s alignment. You can't do too much things to svg but try to do this to h2:
h2 {
display: flex;
align-items: center;
}

FA Icon in placeholder of an input?

As I saw in the documentation, Font Awesome has a way of put an icon in an input placeholder, doing something like this:
<Input placeholder=' Search' />
This is what I get:
No matter what code I put after &#x, it always renders the same icon.
I'm working with ReactJS and Reactstrap library. Any suggestion? Thanks a lot (sorry 4 my english)
You can't do it this way, because the font family of the input field is using an English font. Font Awesome uses it's own font file.
One way to implement this would be to use a positioned <i> element:
<div class="container">
<label><b>Username</b></label>
<input type="text" placeholder="Enter Username" name="uname" required>
<i class="fa fa-user fa-lg"></i>
</div>
.container {
position: relative;
}
.container i {
position: absolute;
left: 15px;
top: 40px;
color: gray;
}

ng-class and class css/style atrributes

I do not know when use one over the other and when I should use both at the same time for an html element (div, span, table, etc). Please advise. Mixing both of them may cause some issues, mayn't it?
Ngclass is used when you need the class to be conditional based on some logic
Such as ng-class="{'choose-this-class': ifThisAngularScopeIsTrue}"
Class is just a fixed class of css
The ng-class directive dynamically binds one or more CSS classes to an HTML element.
Eg: ng-class
You should use class and style attributes as you see fit to your desired designs. The ng-class directive is generally used when you want to change some html's class based on some variable or expression.
Here's a simple example
angular.module('app', []);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<style>
.blue {
height: 100px;
width: 100%;
background-color: blue;
display: block;
}
.red {
height: 100px;
width: 100%;
background-color: red;
display: block;
}
</style>
<div ng-app="app">
<div style="height: 100px; width 100%; background-color: red; display: block;" ng-class="{'red': red == true, 'blue': red == false}"></div>
<br />
<button ng-click="red = !red">Changing Red to Blue won't work because of the style attribute!</button>
<br />
<br />
<div class="blue" ng-class="{'blue': blue, 'red': !blue}"></div>
<br />
<button ng-click="blue = !blue">Toggle between Red & Blue</button>
</div>
Notice how inline style attribute overwrites the class ;)
Do read this for further insight.

Angular Material mdTabs : is it possible to have vertical tabs?

I am looking for Tabs displayed top to bottom with tab navigation on the left. Is there anyway this can be achieved in Angular Material library?
This codepen by Rahul Sagore uses vanilla Material, not specifically for Angular, but it's exactly what you want. I was looking for the same thing as you; it's a shame Material doesn't offer this, but I can see how it would go against their principles and make Material too extensive.
It comprises of custom css (perhaps overriding, I'm not sure) and use of particular Material classnames. Below I've pasted the contents into a snippet.
I had an issue with the mdl-cell--n-col classes so I changed the content one from 10-col to 6-col so it wouldn't wrap the content beneath the tabs in the restrictive space of this post. You'll probably have to tinker with that yourself, or scrap that and use Material styles the way you know how. Similarly, I cannot see what the .hollow-circle spans are doing, so perhaps they aren't needed.
/*Vertical Tabs*/
.vertical-mdl-tabs {
margin-top: 30px;
}
.vertical-mdl-tabs .mdl-tabs__tab-bar {
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
padding-bottom: 35px;
height: inherit;
border-bottom: none;
border-right: 1px solid rgba(10, 11, 49, 0.20);
}
.vertical-mdl-tabs .mdl-tabs__tab {
width: 100%;
height: 35px;
line-height: 35px;
box-sizing: border-box;
letter-spacing: 2px;
}
.vertical-mdl-tabs.mdl-tabs.is-upgraded a.mdl-tabs__tab.is-active {
border-right: 2px solid #ED462F;
}
.vertical-mdl-tabs.mdl-tabs.is-upgraded .mdl-tabs__tab.is-active:after {
content: inherit;
height: 0;
}
.vertical-mdl-tabs.mdl-tabs.is-upgraded .mdl-tabs__panel.is-active, .mdl-tabs__panel {
padding: 0 30px;
}
.vertical-mdl-tabs.mdl-tabs .mdl-tabs__tab {
text-align: left;
}
<script src="https://storage.googleapis.com/code.getmdl.io/1.1.0/material.min.js"></script>
<link href="https://storage.googleapis.com/code.getmdl.io/1.1.0/material.indigo-pink.min.css" rel="stylesheet"/>
<div class="mdl-tabs vertical-mdl-tabs mdl-js-tabs mdl-js-ripple-effect">
<div class="mdl-grid mdl-grid--no-spacing">
<div class="mdl-cell mdl-cell--2-col">
<div class="mdl-tabs__tab-bar">
<a href="#tab1-panel" class="mdl-tabs__tab is-active">
<span class="hollow-circle"></span>
Tab 1
</a>
<a href="#tab2-panel" class="mdl-tabs__tab">
<span class="hollow-circle"></span>
Tab 2
</a>
<a href="#tab3-panel" class="mdl-tabs__tab">
<span class="hollow-circle"></span>
Tab 3
</a>
</div>
</div>
<div class="mdl-cell mdl-cell--6-col">
<div class="mdl-tabs__panel is-active" id="tab1-panel">
Content 1
</div>
<div class="mdl-tabs__panel" id="tab2-panel">
Content 2
</div>
<div class="mdl-tabs__panel" id="tab3-panel">
Content 3
</div>
</div>
</div>
</div>
you can have verticval tabs by adding vertical attribute to the mat-tab-group and adding following css to your page.
mat-tab-group[vertical] .mat-tab-labels {
display: flex;
flex-direction: column!important;
}
mat-tab-group[vertical] {
display: flex;
flex-direction: row!important;
}
here's the mat-tab-group element with vertical attribute
<mat-tab-group flex="1" vertical>
<mat-tab label="Tab 1"> Loading ... </mat-tab>
<mat-tab label="Tab 2" > Loading ... </mat-tab>
</mat-tab-group>

Resources