Checkbox label with URL link in Semantic UI React - semantic-ui-react

Semantic UI React Checkbox can be used like this:
import React from 'react'
import { Checkbox } from 'semantic-ui-react'
const TermsOfServiceCheckbox = () => (
<Checkbox label='I accept the Terms of Service' />
)
export default TermsOfServiceCheckbox
How do I set the Checkbox label so that the text Terms of Service is a link to a URL?

label prop implements the item shorthand, so you can also pass there:
<Checkbox label={<label><a href='/'>I accept the Terms of Service</a></label>} />
<Checkbox label={<label>I accept the <a href='/'>Terms of Service</a></label>} />
<Checkbox label={{ children: <a href='/'>I accept the Terms of Service</a> }} />

Related

Svelte-ChartJS chart binding

I am trying to use svelte-chartjs with chartjs-plugin-zoom. In order to programmatically adjust zoom. In order to do this you have to bind onto the element. This can be illustrated in the React-ChartJS-2 - see buttons below.
Is there a prop in svelte-chartjs to make that binding?
Something like:
<Line chartRef={myrefvar} {options} />
Use bind:property (tutorial) to get the chart reference » REPL
<script>
...
let chartRef
const onZoomPluse = () => {
chartRef.zoom(1.1);
};
</script>
<Line bind:chart={chartRef} options={options} data={data} />
<button on:click={onZoomPluse}>zoom +10%</button>

How do i unit test a react app that has all the text fields in the children components?

I have created a react application that has all the logic (like onchange functions) in the parent and all the html rendering in the children components.
In order to test if the right state changes are happening i have to enter text to the input fields and enter values but the only problem is I dont know how to access the children elements when i mount the parent in js dom.
Should i move logic into the child components or should i only unit test the functions of the parent component?
This is from the parent
render() {
if (!this.state.accessTokenEntered) {
return <AccessTokenPage _onChange={this._onChange}
accessToken={this.state.inputs.accessToken}
env={this.state.inputs.env}
_onFirstClick={this._onFirstClick}/>;
and this is the child
const AccessToken = props =>(
<Layout>
<Input name={"accessToken"} displayName={"Access Token"} _onChange={props._onChange}
value={props.accessToken}/>
<DropDown name={"env"} displayName={"Environment"} _onChange={props._onChange}
data={['ppe', 'prod']} multiple={false}
value={props.env}/>
<br/>
<div style={{"textAlign": "center"}}>
<input type="button" onClick={props._onFirstClick} className="btn btn-primary" value="Submit"/>
</div>
</Layout>
);
and this is the childs child
const Input = props => (
<div className="form-group row">
<label className="col-xs-2 col-form-label">{props.displayName}</label>
<div className="col-xs-10">
<input name={props.name} className="form-control" value={props.value}
onChange={props._onChange}/></div>
</div>
);
You should be testing your child component. When the onChange event of the textbox is simulated, test if the onChange prop is called. This can be done by creating a mock or spy for the onChange prop.
An example test is shown below:
Mocking a prop.
beforeEach(() => {
onAdd = jest.fn();
add = TestUtils.renderIntoDocument(<Add onAdd={onAdd} />);
});
Test if the mock method is called:
it('Button click calls onAdd', () => {
const button = TestUtils.findRenderedDOMComponentWithTag(add, 'button');
const input = TestUtils.findRenderedDOMComponentWithTag(add, 'input');
input.value = 'Name 4';
TestUtils.Simulate.change(input);
TestUtils.Simulate.click(button);
expect(onAdd).toBeCalledWith(input.value);
});
I am using Jest and React TestUtils. Similar code is available for enzyme in my github project.

How to setup "style" attribute on Embers Handlebars {{input}} helper?

I try to use {{input style="width:100%"}} in my view's template but without any success.
Browser stubbornly renders <input> without style="width:100%;".
How can I achieve it?
For future reference, below is my resolution (for Ember-Cli) based on #damienc answer:
Component class
//app/components/forms/elements/style-input.js
import Ember from "ember";
export default Ember.TextField.extend({
attributeBindings: ['style'],
styleAttrib : null,
style: Ember.computed({
get: function () {
return Ember.String.htmlSafe(this.get('styleAttrib'));
},
set: function (key, newStyle) {
this.set('styleAttrib', newStyle);
return Ember.String.htmlSafe(newStyle);
}
})
});
And the template:
{{!app/templates/components/portlet-datatable/header-cell-filterable.hbs}}
<div class="ember-table-content-container">
<span class="ember-table-content">
{{forms/elements/style-input type="text"
placeholder=view.content.headerCellName style="width: 100%;"}}
</span>
</div>
This is not supported out-of-the-box by the input helper.
You could either add a class parameter that matches a CSS rule, or implement your own input helper to add style to your component's attributeBindings attribute.
This old cookbook entry achieves some specific behavior by extending the Ember.TextField class:
http://guides.emberjs.com/v1.10.0/cookbook/user_interface_and_interaction/focusing_a_textfield_after_its_been_inserted/

Is duplicating state of props the only way to go in React.js?

Take a look at the source code given below. It models a form that is composed out of two WHOIS components and a radio button group. The radio button determines the WHOIS component that is selected. Once the selected WHOIS component is valid the form should be submittable and emit the data of the selected WHOIS.
/** #jsx React.DOM */
var Publish = React.createClass({
getInitialState: function() {
return {
type: 'intern',
intern: {
domain: '',
valid: false
},
extern: {
domain: '',
valid: false
}
};
},
updateWhois: function(type, domain, state) {
var newState = {};
newState[type] = {
domain: domain,
valid: state === 'free'
};
this.setState(newState);
},
switchTo: function(type) {
this.setState({
type: type
});
},
isValid: function() {
var type = this.state.type;
var typeState = this.state[type];
return typeState.valid;
},
render: function() {
return (
<form className="publish">
<div>
<input name="publish-type" type="radio" checked={this.state.type === 'intern'} onChange={this.switchTo.bind(this, 'intern')} />
<Whois onFocus={this.switchTo.bind(this, 'intern')} onChange={this.updateWhois.bind(this, 'intern')} />
</div>
<div>
<input name="publish-type" type="radio" checked={this.state.type === 'extern'} onChange={this.switchTo.bind(this, 'extern')} />
<Whois onFocus={this.switchTo.bind(this, 'extern')} onChange={this.updateWhois.bind(this, 'extern')} />
</div>
<input type="submit" disabled={!this.isValid()} />
</form>
);
}
});
This code works perfectly. However I feel I am duplicating the state of the child components. How could I improve this example? Upon submit I would rather query the Whois component directly (for example an .getDomain method), but I have not clue if and how I should do so in ReactJs.
I feel as though there's nothing directly wrong with your example here, as there are different paradigms you can use when writing ReactJS components. If you do want to read from a rendered component, look at the methods in more about refs. Adding a ref property to your whois like so:
<Whois onFocus={this.switchTo.bind(this, 'intern')} onChange={this.updateWhois.bind(this, 'intern')} ref="whoIs1" />
this.refs.whoIs1.getDOMNode();
would make it possible to look at the component after it has been rendered into the DOM. Using the event argument inside a handler for your onChange method would also be a good option, as you can query the component's state out of the properties on event.

Hide div with AngularJS with Django-rendered template

I have a HTML form rendered by Django template tag and I want to manipulate it using AngularJS.
In my template (not rendered) I have:
<html>
<body>
{{ form.as_p }}
</body>
</html>
This is how Django renders this template:
<html>
<body>
<form>
<div id="div_id_street" class="ctrlHolder ">
<label for="id_street">
Street<span>*</span>
</label>
<input id="id_street" type="text" class="textInput textinput" name="street" maxlength="32">
</div>
</form>
</body>
</html>
I want to hide the div div_id_street, but I am not able to add the ng-show or ng-hide directive in my HTML because of the way that Django generates the HTML code.
Is it possible inside an AngularJS controller to show/hide this div?
Thank you!
I was wrong. It is possible to change the template of a Django rendered form.
When defining a django form, I am able to change the widget of each fiels, so I can put the Angular directives in the widget.
For example:
# forms.py
class MyForm(forms.Form):
street = forms.CharField(max_length=80,
widget=forms.TextInput(attrs={
'ng-model': 'street',
'ng-show': 'false',
'ng-change': 'validateStreet()',})
)
This will be rendered as:
<div id="div_street" class="ctrlHolder">
<label for="id_street">Street</label>
<input ng-model="street" name="street" maxlength="80" ng-change="validateStreet()"
ng-show="false" type="text" class="textInput textinput ng-valid ng-dirty"
id="id_street">
</div>
So in my controller I can manipulate this whole field.
Is it possible inside an AngularJS controller to show/hide this div?
Yes, but this "goes deep against the Angular way" -- Misko. Inject $element, then use selectors to find and manipulate. $element is set to the element that your controller is defined on.
function MyCtrl($scope, $element) {
$scope.show = false;
$scope.$watch('show', function (value) {
if (value) {
$element.find('#div_id_street').show();
} else {
$element.find('#div_id_street').hide();
}
})
}
Fiddle -- in this fiddle I used ng-controller.
If you can't modify the template, neither add a class to that specific DIV to add it a ng-show, than you should create a directive to handle this DOM manipulation. You shouldn't do DOM manipulation from within a controller. As stated by the DOCs,
Do not use controllers for:
Any kind of DOM manipulation — Controllers should contain only
business logic. DOM manipulation—the presentation logic of an
application—is well known for being hard to test. Putting any
presentation logic into controllers significantly affects testability
of the business logic. Angular offers databinding for automatic DOM
manipulation. If you have to perform your own manual DOM manipulation,
encapsulate the presentation logic in [directives]http://docs.angularjs.org/guide/directive).
...
I would suggest you to $watch the property you need and manually show/hide the element from inside the link function of a directive.