cy.get('div[id="base-table-\[object\ Object\]-body"] > .MuiGrid-root, .jss505').should('have.length', 10)
How to make a check <=10 ? Maybe to.have.length.most()
DOM
<div id="base-table-[object Object]-body">
<div class = "MuiGrid-root jss505"> </div>
<div class = "MuiGrid-root jss505"> </div>
<div class = "MuiGrid-root jss505"> </div>
<div class = "MuiGrid-root jss505"> </div>
<div class = "MuiGrid-root jss505"> </div>
</div>
You can enhance the assertion as follows
cy.get('div[id="base-table-\[object\ Object\]-body"] > .MuiGrid-root, .jss505')
.should('have.length.lt', 11)
You can use these assertions:
cy.get('div[id="base-table-[object Object]-body"] > .MuiGrid-root, .jss505')
.its('length')
.then((len) => {
expect(len).to.be.lte(10)
})
Or,
cy.get('div[id="base-table-[object Object]-body"] > .MuiGrid-root, .jss505')
.its('length')
.then((len) => {
expect(len).to.be.within(0, 10)
})
You can use the following callback assertion
cy.get('div[id="base-table-[object Object]-body"] > .MuiGrid-root, .jss505')
.should($els => expect($els.length).to.be.lte(10))
Using .should() instead of .then() gives you command retry in async situations.
Related
good day;
i new in vue.js
i have simple problem when i using infinite scroll i make configuration as below but when page reloaded it must send request to data base to show data when page =1 this request not sent
i want help to get it work
this is my
this is service component
<template>
<div>
<!-- start covr-page --------------------- -->
<div class="covr-page">
<h2>خدمات لوجستية متكاملة </h2>
<div class="overlay"></div>
</div>
<!-- end covr-page --------------------- -->
<!-- start servic --------------------- -->
<div class="servic sections">
<div class="container">
<h3 class="start-title">
<img src="/images/start-title.png" alt="">
خدمات لوجستية متكاملة
</h3>
<div class="row">
<div v-for="service,key in list" class="col-lg-offset-3 col-lg-6 col-md-12 col-md-8 col-sm-offset-1 col-sm-10">
<a href="order-service.html">
<div class="email-signature">
<div class="signature-details">
<div class="signature-img">
<img :src="`upload/${service.icon}`" alt="">
</div>
</div>
<div class="contant-serv">
<h4>{{service.ar_name}}</h4>
<p>
{{service.ar_description}}
</p>
</div>
</div>
</a>
</div>
<infinite-loading #distance="100" #infinite="infiniteHandler"></infinite-loading>
</div>
</div>
</div>
</div>
</template>
this is my route
Route::get('/Services', 'ServicesController#Services');
this is my js code
<script>
export default {
name: "Services",
data: function () {
return {
list: [],
page:1
}
},
mounted(){
// this.infiniteHandler()
// axios.get('/Services')
// .then((response) =>{
// this.list=response.data
// }).catch((error) =>this.errors=error.response.data.errors );
},
methods: {
infiniteHandler($state) {
this.$http.get('/Services?page='+this.page)
.then(response => {
return response.json();
}).then(data => {
$.each(data.data, (key, value)=> {
this.list.push(value);
});
$state.loaded();
});
this.page = this.page + 1;
},
},
}
</script>
you have not declared vue-infinite-loading
import InfiniteLoading from 'vue-infinite-loading';
export default {
components: {
InfiniteLoading,
},
I'm a begginer in React. I'm trying to fetch an array of data about orders and that is working and then map it to display specific information about each order.
I'm getting TypeError: orders.map is not a function exception in my application.
Here's my code:
class Orders extends Component {
state = {
orders: []
};
componentDidMount() {
axios
.get("https://localhost:9090/orders")
.then(res => {
this.setState({ orders: res.data });
console.log(res.data);
});
}
render() {
const { orders } = this.state;
const orderList =
this.state.orders.length > 0 ? (
orders.map(o => {
return (
<div key={o.orderId}>
<p>
{o.isbn}
</p>
</div>
);
})
) : (
<div className="row p-5 m-5">
<div className="offset-sm-5 col-sm-2 text-center">
<span className="text-grey r">Loading...</span>
</div>
</div>
);
return <div className="container">{orderList}</div>;
}}
What's interesting, I have a similar code, that is working. The only difference is basically what it's fetching. Here's the code:
class BookList extends Component {
state = {
books: []
};
componentDidMount() {
console.log(this.props.match.params.search_term);
axios
.get("https://localhost:8080/search?searchTerm=" + search_term)
.then(res => {
this.setState({ books: res.data });
console.log(res.data);
});
}
render() {
const { books } = this.state;
const booksList =
this.state.books.length > 0 ? (
books.map(b => {
return (
<div key={b.isbn} className="card">
<div className="card-body">
<h5 className="card-title">
<Link to={"/details/" + b.isbn}>{b.title}</Link>
</h5>
<div className="card-subtitle text-muted">
{b.author} ({b.year}) /{" "}
<span className=" text-danger">{b.category}</span>
</div>
<p />
</div>
</div>
);
})
) : (
<div className="row p-5 m-5">
<div className="offset-sm-5 col-sm-2 text-center">
<span className="text-grey r">Loading...</span>
</div>
</div>
);
return <div className="container">{booksList}</div>;
}}
I can't find the difference that would cause that exception. It is an array in both cases.
Any suggestions?
EDIT:
here's the output of response data:
response data of order
response data of bokstore
From them images it looks like the orders are processed as plain text and not parsed to JSON. Check that your back-end specifies the required headers Content-Type: application/json so that axios will parse the data correctly.
Alternatively you could parse the text client-side with JSON.parse(res.data)
I have been unable to get the validation to work on an edit model-view that has data bound to it in the activate method of its view-model.
I have a created.ts which works on an object with the same fields. This file has almost the same code - the exception is that since this one is a create, no data needs to be loaded to it. In this case, the validation is working properly.
If I comment the code that loads the data for the edit model-view - in the activate method - the validation works properly.
Needless to say I am new to SPA, Aurelia and TypeScript and need some help!!
Below is the code in edit.ts
import { ContactRepository } from "./contactRepository";
import { autoinject } from "aurelia-framework";
import { ContactForEditDto } from "./contactForEditDto";
import { json } from "aurelia-fetch-client";
import { inject, NewInstance } from "aurelia-dependency-injection";
import { ValidationRules, ValidationControllerFactory, validateTrigger,
Validator } from "aurelia-validation";
#autoinject
export class Edit {
public saveStatusMessage: string;
public isSaved: number = -1;
private controller = null;
private validator = null;
public canSave: boolean = false;
constructor(public contactForEdit: ContactForEditDto, private repository:
ContactRepository, private controllerFactory: ValidationControllerFactory,
public contactFullName: string, validator: Validator) {
console.log("starting edit controller");
this.controller = controllerFactory.createForCurrentScope(validator);
this.controller.validateTrigger = validateTrigger.changeOrBlur;
this.validator = validator;
this.controller.subscribe(event => this.validateWhole());
ValidationRules
.ensure((c: ContactForEditDto) => c.contactFirstName)
.displayName("First Name")
.required().withMessage("\${$displayName} cannot be empty.")
.maxLength(50).withMessage("\${$displayName} cannot have more than 50 characters.")
.ensure((c: ContactForEditDto) => c.contactLastName)
.displayName("Last Name")
.required().withMessage("\${$displayName} cannot be empty.")
.maxLength(50).withMessage("\${$displayName} cannot have more than 50 characters.")
.ensure((c: ContactForEditDto) => c.contactEmailAddress)
.displayName("Email Address")
//.required().withMessage("\${$displayName} cannot be empty.")
.email().withMessage("\${$displayName} needs to be in a correct email address format.")
.maxLength(50).withMessage("\${$displayName} cannot have more than 50 characters.")
.ensure((c: ContactForEditDto) => c.contactPhoneNumber)
.displayName("Phone Number")
.required().withMessage("\${$displayName} cannot be empty.")
.maxLength(12).withMessage("\${$displayName} cannot have more than 12 characters.")
.matches(/\d{3}-\d{3}-\d{4}/).withMessage("'${$value}' is not a valid \${$displayName}. Please enter a phone in the format xxx-xxx-xxxx")
.on(ContactForEditDto);
}
// source https://www.jujens.eu/posts/en/2017/Jan/24/aurelia-validation/
workaround 3
validateWhole() {
this.validator.validateObject(this.contactForEdit)
.then(results => this.canSave = results.every(result => result.valid));
}
// Returning data from here because I can return a promise
// and let the router know when i have retrieved my initial data.
// Activate receives a params object as defined in the route.
activate(params) {
console.log("ACTIVATE ON EDIT PARAMS:" + params);
this.repository
.getById(params.id)
.then(data => {
console.log(data);
this.contactForEdit = data;
this.contactFullName = this.contactForEdit.contactLastName + ", " +
this.contactForEdit.contactFirstName; // This needs to come from a method
in
contact.
});
}
edit() {
this.saveStatusMessage = "";
this.isSaved = -1;
// This will be an edit
if (this.contactForEdit.contactId >= 1) {
this.repository
.update(this.contactForEdit)
.then(response => {
if (((response.status == 201) || (response.status == 204))
&& (response.ok == true)) {
this.isSaved = 1;
this.saveStatusMessage = "Successfully saved the contact";
}
else {
this.isSaved = 0;
//response.json().then(json => this.retVal = json);
//TODO: get more details about the error.
if (response.status == 400) {
this.saveStatusMessage = "Unable to save the contact. Please make sure that you entered correct values for every field and try again.";
}
else {
this.saveStatusMessage = "Unable to save the contact.";
}
}
});
}
}
clearContactFields() {
this.contactForEdit = new ContactForEditDto(-1, "", "", "", "");
}
}
Below is the code in edit.html
<template>
<form id="editContact" submit.delegate="edit()">
<!-- placeholder for status messages. If equal to 1 display it. If equals to
-1 or 1 hide this.-->
<div id="successStatusMessage" class.bind="isSaved == 1 ? 'visible' :
'hidden'">
<div id="divSuccessMessage" class="alert alert-success">
×
<!--<span class="glyphicon glyphicon glyphicon-ok" aria-hidden="true">
</span> TODO: How to get the glyphicon working? -->
<span class="sr-only"> Success:</span> ${saveStatusMessage}
</div>
</div>
<!-- placeholder for status messages. If equal to 0 is in error, so dislay error message. if equals to -1 or 1 hide this.-->
<div id="errorStatusMessage" class.bind="isSaved == 0 ? 'visible' : 'hidden'">
<!-- placeholder for status messages. -->
<div id="divErrorMessage" class="alert alert-danger">
×
<!-- <span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span> TODO: class="glyphicon glyphicon-exclamation-sign" how to get these in here for class? -->
<span class="sr-only"> Error:</span> ${saveStatusMessage}
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<div class="panel-title">
<!--<div if.bind="isCreate">
"Create a Contact"
</div>
<div if.bind="!isCreate">
Edit ${contactForEdit.contactFirstName}
</div>-->
${ "Edit " + contactFullName }
</div>
</div>
<div class="panel-body">
<div class="form-horizontal">
<div class="form-group" validation-errors.bind="editFirstNameErrors"
class.bind="editFirstNameErrors.length ? 'has-error' : ''">
<label class="control-label col-md-2">First Name: </label>
<div class="col-md-10">
<input type="text"
placeholder="First Name"
class="form-control"
value.bind="contactForEdit.contactFirstName & validate" required /> <!-- NO ${} !!!-->
<span class="help-block" repeat.for="editErrorInfo of editFirstNameErrors">
${editErrorInfo.error.message}
</span>
</div>
</div>
<div class="form-group" validation-errors.bind="editLastNameErrors"
class.bind="editLastNameErrors.length ? 'has-error' : ''">
<label class="control-label col-md-2">Last Name: </label>
<div class="col-md-10">
<input type="text"
placeholder="Last Name"
class="form-control"
value.bind="contactForEdit.contactLastName & validate" required /> <!-- NO ${} !!!-->
<span class="help-block" repeat.for="editErrorInfo of editLastNameErrors">
${editErrorInfo.error.message}
</span>
</div>
</div>
<div class="form-group" validation-errors.bind="emailErrors"
class.bind="editEmailErrors.length ? 'has-error' : ''">
<label for="emailAddress" class="control-label col-md-2">Email: </label>
<div class="col-md-10">
<input id="emailAddress"
type="text"
placeholder="Email Address (format: email#domain.com)"
class="form-control"
value.bind="contactForEdit.contactEmailAddress & validate" /> <!-- NO ${} !!!-->
<span class="help-block" repeat.for="editErrorInfo of editEmailErrors">
${editErrorInfo.error.message}
</span>
</div>
</div>
<div class="form-group" validation-errors.bind="editPhoneErrors"
class.bind="editPhoneErrors.length ? 'has-error' : ''">
<label class="control-label col-md-2">Phone: </label>
<div class="col-md-10">
<input type="text"
placeholder="Phone Number (format: xxx-xxx-xxxx)"
class="form-control"
value.bind="contactForEdit.contactPhoneNumber & validate" required /> <!-- NO ${} !!!-->
<span class="help-block" repeat.for="editErrorInfo of editPhoneErrors">
${editErrorInfo.error.message}
</span>
</div>
</div>
<button type="submit" class="btn btn-default ${canSave ? '' : 'disabled'}">
<!-- Look at click.dependent when there are child with buttons calling this.-->
Save
</button>
<!-- AA-10-17-17 - replaced with errors per input field. <ul for.bind="controller.errors">
<li repeat.for="error of controller.errors" style="color:red">
${error.message}
</li>
</ul>-->
</div>
</div>
</div>
</form>
<div>
<a route-href="route: home"
class="btn btn-default">
Back to list
</a>
</div>
</template>
I expect it's because of this code:
.getById(params.id)
.then(data => {
console.log(data);
this.contactForEdit = data;
your validation is against a ContactForEditDto object, but my guess is your repository is returning a JSON object cast to a ContactForEditDto, so it's not actually a class at all.
Try something like
console.log(data);
this.contactForEdit = new ContactForEditDto(data.id, data.firstname ..etc..);
or
console.log(data);
this.contactForEdit = Object.assign(new ContactForEditDto(), data);
We just had a similar problem and solved it by setting up our validations after assigning the remote data to our local field. In your code, you'd set up your validation rules after this.contactForEdit = data;
I'm doing a webapp using github search API. I want the info for each repo to be displayed under the specific repo.
I want the content from the AJAX request to be displayed when the specific button is being pressed. I am using React. Since I'm using item.x to access the information I need to get that item and I assume I need to use map but when doing that it will display all the results and not just the specific repository's. Anyway that I can get the Item since it currently says it's undefined?
let searchTerm;
class SearchBox extends React.Component {
constructor(props) {
super(props);
this.onClick = this.onClick.bind(this);
this.state = { repositories: [],
showInfo: false };
}
render() {
let moreDetail;
if(this.state.showInfo){
moreDetail= <div className="info"> <li>
<p>Open issue count </p>:{item.open_issues_count}
</li>
<li>
<p>Number of forks </p>:{item.forks}
</li>
<li>
<p>Language </p>:{item.language}
</li></div>;
}
return(
<div>
<form>
<input type="text" className="searchbox" ref={(input) => { this.searchBox = input; }}/>
<button onClick={this.onClick}>Search</button>
</form>
<h2>Repositories</h2>
<ul>
{ this.state.repositories.map( ( item, index ) => (
<div key={ index }>
<a href={item.html_url}> <li >
{ item.name }
</li>
</a>
{moreDetail}
<button onClick={this._handleClick.bind(this)}>Detailed view</button>
</div>
)) }
</ul>
</div>
);
}
_handleClick(){
this.setState({
showInfo: !this.state.showInfo
});
}
onClick(event) {
searchTerm = this.searchBox.value;
let endpoint = 'https://api.github.com/search/repositories?sort=stars&order=desc&q=' + searchTerm;
console.log(searchTerm);
fetch(endpoint)
.then(blob => blob.json())
.then(response => {
this.setState({ repositories: response.items });
});
event.preventDefault();
}
}
The problem is with context. When you define the moreDetail variable, you don't have item in your context (only during the map function you have that.)
One option is to use the variable moreDetail as a function that receives the item you want to show.
Your render method should look something like:
render() {
const moreDetail = (item) => ( !this.state.showInfo ? <span /> :
<div className="info">
<li>
<p>Open issue count </p>:{item.open_issues_count}
</li>
<li>
<p>Number of forks </p>:{item.forks}
</li>
<li>
<p>Language </p>:{item.language}
</li>
</div>
);
return (
<div>
<form>
<input type="text" className="searchbox" ref={(input) => { this.searchBox = input; }}/>
<button onClick={this.onClick}>Search</button>
</form>
<h2>Repositories</h2>
<ul>
{ this.state.repositories.map( ( item, index ) => (
<div key={ index }>
<a href={item.html_url}> <li >
{ item.name }
</li>
</a>
{moreDetail(item)}
<button onClick={this._handleClick.bind(this)}>Detailed view</button>
</div>
)) }
</ul>
</div>
);
}
I want to make dynamic input that save an image to my website.
I use yii2-dynamicform and Kartik input file extension. But, it always save it as null.
Thank you for your help
Ps : ... is other part of my code that not relevant with this question. :)
In controller :
<?php
namespace frontend\controllers;
use Yii;
use common\models\Election;
use common\models\ElectionSearch;
use common\models\Model;
use common\models\Kandidat;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\data\ActiveDataProvider;
use yii\web\Session;
use yii\web\UploadedFile;
use yii\helpers\ArrayHelper;
class ElectionController extends Controller
{
...
public function actionCreate()
{
$model = new Election();
$modelsKandidat = [new Kandidat];
if ($model->load(Yii::$app->request->post())){
$model->save();
$modelsKandidat = Model::createMultiple(Kandidat::classname());
Model::loadMultiple($modelsKandidat, Yii::$app->request->post());
// validate all models
$valid = $model->validate();
$valid = Model::validateMultiple($modelsKandidat) && $valid;
if ($valid) {
$transaction = \Yii::$app->db->beginTransaction();
try {
if ($flag = $model->save(false)) {
foreach ($modelsKandidat as $modelKandidat) {
$modelKandidat->id_election = $model->id_election;
if($modelKandidat->file = UploadedFile::getInstance($modelKandidat,'file'))
{
$imageName = date('dmyhis_').$modelKandidat->id_election;
$modelKandidat->file->saveAs('../../common/file/fotokandidat/'.$imageName.'.'.$modelKandidat->file->extension);
$modelKandidat->foto = $imageName.'.'.$modelKandidat->file->extension;
}
if (! ($flag = $modelKandidat->save(false))) {
$transaction->rollBack();
break;
}
}
}
if ($flag) {
$transaction->commit();
return $this->redirect(['view', 'id' => $model->id_election]);
}
} catch (Exception $e) {
$transaction->rollBack();
}
}
} else {
return $this->render('create', [
'model' => $model,
'modelsKandidat' => $modelsKandidat,
]);
}
}
...
}
In _form :
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use kartik\file\FileInput;
use yii\helpers\ArrayHelper;
use dosamigos\datepicker\DatePicker;
use wbraganca\dynamicform\DynamicFormWidget;
?>
<div class="election-form">
<?php $form = ActiveForm::begin(['options'=>['enctype'=>'multipart/form-data', 'id' => 'dynamic-form']]); ?>
...
<!-- mulai input kandidat !-->
<div class="row">
<div class="panel panel-default">
<div class="panel-heading"><h4><i class="glyphicon glyphicon-envelope"></i>Vote</h4></div>
<div class="panel-body">
<?php DynamicFormWidget::begin([
'widgetContainer' => 'dynamicform_wrapper', // required: only alphanumeric characters plus "_" [A-Za-z0-9_]
'widgetBody' => '.container-items', // required: css class selector
'widgetItem' => '.item', // required: css class
'limit' => 4, // the maximum times, an element can be cloned (default 999)
'min' => 1, // 0 or 1 (default 1)
'insertButton' => '.add-item', // css class
'deleteButton' => '.remove-item', // css class
'model' => $modelsKandidat[0],
'formId' => 'dynamic-form',
'formFields' => [
'nama',
'deskripsi',
'riwayat',
'file',
],
]); ?>
<div class="container-items"><!-- widgetContainer -->
<?php foreach ($modelsKandidat as $i => $modelsKandidat): ?>
<div class="item panel panel-default"><!-- widgetBody -->
<div class="panel-heading">
<h3 class="panel-title pull-left">Kandidat</h3>
<div class="pull-right">
<button type="button" class="add-item btn btn-success btn-xs"><i class="glyphicon glyphicon-plus"></i></button>
<button type="button" class="remove-item btn btn-danger btn-xs"><i class="glyphicon glyphicon-minus"></i></button>
</div>
<div class="clearfix"></div>
</div>
<div class="panel-body">
<?php
// necessary for update action.
if (! $modelsKandidat->isNewRecord) {
echo Html::activeHiddenInput($modelsKandidat, "[{$i}]id_kandidat");
}
?>
<div class="row">
<div class="col-sm-4">
<?= $form->field($modelsKandidat, "[{$i}]nama")->textInput(['maxlength' => true]) ?>
</div>
<div class="col-sm-4">
<?= $form->field($modelsKandidat, "[{$i}]deskripsi")->textarea(['rows' => 6]) ?>
</div>
<div class="col-sm-4">
<?= $form->field($modelsKandidat, "[{$i}]riwayat")->textarea(['rows' => 6]) ?>
</div>
<div class="col-sm-4">
<?= $form->field($modelsKandidat, "[{$i}]file")->fileInput() ?>
</div>
</div><!-- .row -->
</div>
</div>
<?php endforeach; ?>
</div>
<?php DynamicFormWidget::end(); ?>
</div>
</div>
</div>
<!-- selesai input kandidat !-->
...
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
It's from #shoara/#zahraj answer :
I think you forgot to specify index for your file `
foreach ($modelsKandidat as $keyindex=>$modelKandidat)
{
$modelKandidat->id_election = $model->id_election;
if ($modelKandidat->file = UploadedFile::getInstance($modelKandidat, "[{$keyindex}]file")) {
.......
}
}
see demo controller and form part,imagine $modelCatalogOption in demo is your $model = new Election(); and $modelsOptionValue is your $modelsKandidat = [new Kandidat]; if you try and check your values in your controller I'm sure you can solve this problem easily. Pay attention to actionCreate