I have one checkbox and two input fields I want if I check checkbox then second (b) input box is require otherwise first (a) input field in require.
<input type="checkbox" name="try" id="try" value="on">
<input type="text" name="a" id="a">
<input type="text" name="b" id="b">
$validator = Validator::make($request->all(), [
'a' => 'nullable|required_if:try,off',
'b' => 'nullable|required_if:try,on'
]);
Try but not success. Please Help. Edit [Typo in required_if]
First, you need to define rule on try input like :
$this->validate($request, [
'a' => 'partialARequired',
'b' => 'partialBRequired'
]);
Then you must define your partialRequired method's definition:
class customValidation extends Validator
{
public function validatePartialARequired($attribute, $value, $parameters)
{
if(!in_array('try',$this->data) && empty($value))
{
return false;
}
return true;
}
public function validatePartialBRequired($attribute, $value, $parameters)
{
if(in_array('try',$this->data) && empty($value))
{
return false;
}
return true;
}
}
Related
I use react-native-elements library.
in ListItem Accordion there is onPress option to expand and unexpand list items.
but when I press one item, all of items expand!
screen shot 1
here is part of my code:
export class MyList extends Component {
state= {
expanded:false,
};
constructor(props) {
super(props);
this.state = {
expanded:false
};
}
handleToggle=()=>{
const {expanded}=this.state;
if(expanded){
this.setState({expanded:false});
}else{
this.setState({expanded:true})
}
}
render() {
return (
...
<View>
{list.map((l, i) => (
<ListItem.Accordion key={i}
content={
<>
<ListItem.Content>
<ListItem.Title>{l.name}</ListItem.Title>
<Avatar title={l.name[0]} source={{ uri: l.avatar_url }} />
</ListItem.Content>
</>
}
isExpanded={this.state.expanded}
onPress={this.handleToggle}
>
<ListItem key={i} bottomDivider>
<ListItem.Content>
<ListItem.Subtitle>{l.city}</ListItem.Subtitle>
<View style={styles.subtitleView}>
<Image source={require('../Images/4.5_stars.svg.png')} style={styles.ratingImage}/>
<Text style={styles.ratingText}>5 votes</Text>
</View>
</ListItem.Content>
<ListItem.Chevron />
</ListItem>
</ListItem.Accordion>
))}
...
is it my props problem?? if yes, how can I pass the item for each "onPress"??
Surely you already solved your problem.
I had the same problem and I solved it myself since I couldn't find a solution.
It turns out that it was very simple and probably arises from not being used to the React way of working.
A component must be created for your custom <ListItem.Accordion>,
then you get something like
{Turneras ? (Turneras.map((Turnera, i) => (
<ItemAccordion Turnera={Turnera} ></ItemAccordion>
))) : null
}
As easy as that, since each component will have its state expanded and it works perfectly.
Based on other examples, my regex attempt to replace dashes (-) with letters should work. But it doesn't. I am using React.
I have followed this post (Replace multiple characters in one replace call) and other outside posts but I cannot get regex to replace dashes (-) with certain letters. The app only has one component, App.js. I have also tried writing the line targetNameDashes.replace(/'-'/gi, letter).toUpperCase(); but it hasn't worked either.
GitHub repo: https://github.com/irene-rojas/brooklyn-react
import React, { Component } from 'react';
import './App.css';
class App extends Component {
state = {
names: ['JAKE', 'AMY', 'GINA', 'ROSA', 'CHARLES', 'TERRY', 'HOLT'],
targetName: "",
targetNameDashes: "",
guessRemain: 10,
lettersGuessed: []
}
componentDidMount() {
let targetName = this.state.names[Math.floor(Math.random()*this.state.names.length)];
this.setState({
targetName: targetName,
targetNameDashes: targetName.replace(/[a-zA-Z]/gi , '-').toUpperCase(),
// The flags 'g' and 'i' are for global search and case insensitive search
});
console.log(targetName);
}
onKeyUp = (event) => {
event.preventDefault();
let letter = event.key.toUpperCase();
let targetName = this.state.targetName;
let guessRemain = this.state.guessRemain;
let lettersGuessed = this.state.lettersGuessed;
if (letter) {
this.setState({
guessRemain: guessRemain - 1,
lettersGuessed: lettersGuessed + letter
});
// if letter is in targetName, replace dash with letter
if (targetName.includes(letter)) {
console.log("yup");
let targetNameDashes = this.state.targetNameDashes;
// temporary variable that contains dashes and letters?
targetNameDashes.replace(/-/gi, letter).toUpperCase();
this.setState({
targetNameDashes: targetNameDashes
// does it need a callback to update?
});
}
}
if (guessRemain === 0) {
console.log("too bad");
this.setState({
guessRemain: 10,
lettersGuessed: []
});
this.componentDidMount();
}
console.log(`${letter} end of onKeyUp`);
}
render() {
return (
<div className="App">
<div>
You will be seen by:
<br></br>
{this.state.targetNameDashes}
</div>
<br></br>
<div>
Letters guessed:
<br></br>
<input onKeyUp={this.onKeyUp} />
<br></br>
Letters guessed in this round:
<br></br>
[ {this.state.lettersGuessed} ]
</div>
<br></br>
<div>
Guesses remaining:
<br></br>
{this.state.guessRemain}
</div>
</div>
);
}
}
export default App;
I noticed many issues that I should mention one by one:
Move some of the constants out of the state, for example names. Setting them in state makes no sense because they will not be changed and re-rendered in UI.
You manually called componentDidMount at the end of your key up event handler, which is not they way this should be done. Separate the logic that needs to be re-done in a separate utility function (i.e. gameReset() and call that instead).
The replace logic of the case when targetName.includes(letter) is not correct. It doesn't know which indices to replace.
Think of that this way: your targetName was "EVE", you are asking
a string that looks like "---" to change to wherever "E" is. How can
it know where "E" is without inspecting the original name? A loop
would be a better solution.
setState is asynchronous in nature. You should make use of prevState argument and callback method to ensure you are getting the correct states.
Here I have modified your codes and added comments where necessary, hope it helps:
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
// moved it outside state
const names = ["JAKE", "AMY", "GINA", "ROSA", "CHARLES", "TERRY", "HOLT"];
class App extends React.Component {
state = {
targetName: "",
targetNameDashes: "",
guessRemain: 10,
lettersGuessed: []
};
// utility extracted from componentDidMount
// so that it can be re-used later
resetGame = () => {
let targetName = names[Math.floor(Math.random() * names.length)];
this.setState({
guessRemain: 10,
lettersGuessed: [],
targetName: targetName,
targetNameDashes: new Array(targetName.length).fill("-").join("") // fill an array with hyphens
});
};
componentDidMount() {
// call the utility
this.resetGame();
}
onKeyUp = event => {
event.preventDefault();
let letter = event.key.toUpperCase();
// TODO: provide more logic to avoid bad key strokes
// for example backspace should not count
if (letter) {
this.setState(
prevState => {
let modifiedNameDashes = String(prevState.targetNameDashes);
// for each charecter of targetName
for (var i = 0; i < prevState.targetName.length; i++) {
// check if this charecter at index i matched the key
if (prevState.targetName[i] === letter) {
// if it does
// remove a hyphen from modifiedNameDashes at that exact index
modifiedNameDashes =
modifiedNameDashes.substr(0, i) +
letter +
modifiedNameDashes.substr(i + 1);
}
}
return {
targetNameDashes: modifiedNameDashes,
guessRemain: prevState.guessRemain - 1,
lettersGuessed: [...prevState.lettersGuessed, letter]
};
},
// callback after the state update is done
() => {
// won
if (this.state.targetNameDashes === this.state.targetName) {
console.log("Nice!");
}
// lost
if (this.state.guessRemain === 0) {
this.resetGame();
}
}
);
}
};
render() {
return (
<div className="App">
<div>
You will be seen by:
<br />
{this.state.targetNameDashes}
</div>
<br />
<div>
Letters guessed:
<br />
<input onKeyUp={this.onKeyUp} />
<br />
Letters guessed in this round:
<br />[ {this.state.lettersGuessed} ]
</div>
<br />
<div>
Guesses remaining:
<br />
{this.state.guessRemain}
</div>
<code>{JSON.stringify(this.state)}</code>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
targetNameDashes.replace(/-/gi, letter).toUpperCase();
this.setState({
targetNameDashes: targetNameDashes
// does it need a callback to update?
});
This is likely the source of your problem with nothing happening - String.prototype.replace returns a new version of the string, and doesn't modify the parameter string.
This would at least cause it to update so you can continue to work on the logic here.
this.setState({
targetNameDashes: targetNameDashes.replace(/-/gi, letter).toUpperCase()
});
Is it possible to use a Modal without a trigger? I will open and close it via state.
For example, I want to use onClick on an input field(with a file name) to open the modal with a file chooser and then edit the name of the choosen file in the input field. All this in a nested modal...
Looks much simpler if I will have both modals in a parent component without the triggers, and I will display/hide them via open={true/false}
Thanks
Yes it is. Don't set the prop trigger (it is not required) and just provide the open value from state/props.
class container extends Component {
state = {
isParentOpen: false,
isChildOpen: false
}
handleClick = () => {
this.setState({
isParentOpen: !this.state.isOpen
});
}
handleFocus = () => {
this.setState({
isChildOpen: true
});
}
render() {
return (
<div>
<Modal
open={this.state.isParentOpen}
size="large"
>
...
<Input onFocus={this.handleFocus} />
</Modal>
<Modal
open={this.state.isChildOpen}
size="small"
>
...
</Modal>
<Button onClick={this.handleClick} />
</div>
);
}
}
(You can nest Modal if you want to)
Pass a prop to the modal component and fire handleOpen according to the prop on ComponentDidMount. This will allow the modal to be closed.
class ModalContainer extends Component {
componentDidMount() {
const { startOpen } = this.props;
if (startOpen) {
this.handleOpen();
}
}
handleOpen = () => this.setState({ modalOpen: true });
handleClose = () => this.setState({ modalOpen: false });
render() {
return (
<Modal open={this.state.modalOpen} onClose={this.handleClose} />
)
}
I'm trying to build a simple login system and I have 2 different templates in it: One when the user is not logged in yet (which displays a "sign in" button), and one when the user is logged in (which displays the username)
By default, the first one is displayed. But when the user is logged in, my first template is not destroyed and my second template is not displayed.
<template is="dom-if" if="{{!logged}}" restamp="true">
<div class="box" id="notLogged">
<paper-button class="loginButton" on-tap="loginPopup"><iron-icon class="avatar" icon="account-circle"></iron-icon><span id="notLoggedMessage">Sign in</span></paper-button>
</div>
</template>
<template is="dom-if" if="{{logged}}" restamp="true">
<div class="box" id="logged">
<paper-button class="loginButton" on-tap="logoutPopup">
<img src="https://placehold.it/40x40" alt="user avatar" />
</paper-button>
</div>
</template>
and now the script. As you can see, I don't use any ajax yet because the service is not done yet. So I'm faking it with "loginOk" value
Polymer({
is: 'system-login',
properties: {
logged: {
type: Boolean,
value: false}
},
loginPopup: function (e) {
loginWindow.open();
},
logoutPopup: function (e) {
logoutWindow.open();
},
checkLogin: function () {
var loginOk = 1;
if (loginOk === 1) {
this.logged === true;
loginWindow.close();
} else if (loginOk === 2) {
errorMessage.style.display = "inline";
} else {
return;
}
}
});
The problem is this.logged === true;. === in JavaScript is a comparison operator and not an assignment operator. So what your code does is it compares the value and type of this.true with Boolean true and returns false (which you are not catching).
Changing it to this.logged = true should do the trick
I'm trying to implement this (the one at the bottom of the page) RegExp to validate email addresses with jquery validation plugin.
This is my code:
$.validator.addMethod("email_address", function(value, element, param) {
var email_regexp = new RegExp("[a-z0-9!#$%&'*+/=?^_{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_{|}~-]+)*#(?:a-z0-9?.)+(?:[A-Z]{2}|com|org|net|edu|gov|mil|biz|info|mobi|name|aero|asia|jobs|museum)\b", "g");
var result = value.match(email_regexp);
return result ? result.length >= param : false;
}, "Invalid email address");
No JS errors are shown, still it doesn't validate anything! Been playing with it for like an hour and can't get this working!
Is there something wrong?
EDIT: I tried also with // delimiters:
$.validator.addMethod("email_address", function(value, element, param) {
var result = value.match(/[a-z0-9!#$%&'*+/=?^_{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_{|}~-]+)*#(?:a-z0-9?.)+(?:[A-Z]{2}|com|org|net|edu|gov|mil|biz|info|mobi|name|aero|asia|jobs|museum)\b/g);
return result ? result.length >= param : false;
}, "Invalid email address");
~-]+(?:\.[a-z0-9!#$
// ^^
That \. will need escaping again for the Javascript string:
~-]+(?:\\.[a-z0-9!#$
// ^^^
Or, preferably, use // delimeters rather than constructing a RegExp object from a string.
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp
Why are you writing a custom regex function for the jQuery Validate plugin when it already has an email rule built-in?
http://docs.jquery.com/Plugins/Validation/Methods/email
jQuery:
$(document).ready(function() {
$('#myform').validate({
rules: {
field: {
required: true,
email: true
}
}
});
});
HTML:
<form id="myform">
<input type="text" name="field" /> <br/>
<input type="submit" />
</form>
Working Demo:
http://jsfiddle.net/sRwHc/
The default regex function used within the .validate() plugin, FYI:
email: function(value, element) {
// contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/
return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))#((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(value);
}