chaining queryselectors in puppteer - jquery-selectors

how can I chain query selectors in puppteer like we do in protractor?
return this.page.$$(".stop.departed").$$eval(".station",el=>el.innerText)
I get TypeError: this.page.$$(...).$$eval is not a function
My Html is
<div class="stop departed">
<div class="left">
<div class="station">London
</div>
<div class="scheduled">Dept. 10:47
</div>
</div>
</div>
<div class="stop departed">
<div class="left">
<div class="station">Paris
</div>
<div class="scheduled">Dept. 12:47
</div>
</div>
</div>
I want to get all station names in a list ["London", "Paris"].

Both methods, page.$$(), and elementHandle.$$eval() return promises, so you must await them both.
The functions also both run querySelectorAll() on the selectors, so you must specify the element by index before running the next operation (or iterate through all indexes).
The following example will return the first station at the first stop:
const first_station = await ( await page.$$( '.stop.departed' ) )[0].$$eval( '.station', el => el[0].innerText );
console.log( first_station ); // London
Alternatively, you can use the following example to obtain an array of stations for each stop:
const stations = await Promise.all(
( await page.$$( '.stop.departed' ) ).map( el => el.$$eval( '.station', el => el.map( el => el.innerText ) ) )
);
console.log( stations.length ); // 2
console.log( stations[0].length ); // 1
console.log( stations[1].length ); // 1
console.log( stations[0][0] ); // London
console.log( stations[1][0] ); // Paris
Or if every stop only has one station, you can use:
const stations = await Promise.all(
( await page.$$( '.stop.departed' ) ).map( el => el.$$eval( '.station', el => el[0].innerText ) )
);
console.log( stations.length ); // 2
console.log( stations[0] ); // London
console.log( stations[1] ); // Paris

Related

How to update Form options after submitting using useReducer

i´m new at programming..
I'm coding a form that has a Select list of Options, which come from an array of objects (i named it initialState for useReducer use).
Now i have to use the useReducer hook to update those options when the form is submitted. The submitted option has to be eliminated after submitting.
I just started coding the hook, but i really don´t know what to do...
The app is rendering OK, and the "placeholder" initial state is showing the first option value. I'm okay with that.
Can you help me plase? Thanks!
import { useState, useReducer } from "react";
const handleSubmit = (e) => {
e.preventDefault();
}
const BookingForm = () => {
const initialState = [
{value: "17:00"},
{value: "17:30"},
{value: "18:00"},
{value: "18:30"},
{value: "19:00"},
{value: "19:30"}]
const reducer = (state, action) => {
?????? }
const [state, dispatch] = useReducer(reducer, initialState);
const [option, setOption] = useState({initialState});
return(
<div className="form_div">
<form className="form" onSubmit={handleSubmit}>
<label htmlFor="res-time" className="label">Choose time
<select id="res-time " className="input"
value={option}
onChange={(e) => setOption(e.target.value)}>
{initialState.map(item => {
return (<option key={item.value} value={item.value}>{item.value}</option>);
})}
</select>
</label>
<input type="submit" value="Make Your reservation" className="button" onClick={() => dispatch({type: "selected option"})}/>
</form>
export default BookingForm;

invisible reCAPTCHA javascript

I have the invisible reCAPTCHA set up, but it doesn't seem to want to call my callback function. My form looks like:
<form id='ContactAgentForm' name='ContactAgentForm' class='custom-form-widget-form standard_form' action='contact_agent' listing_id=1233445>
...
<div class='field captcha-field recaptcha_field' >
<div id='g-recaptcha-div' class="g-recaptcha" ></div>
</div>
...
<div class="field button-field">
<button class="button button-primary"><span>Send</span></button>
<a class="button button-cancel btn-close" href="#cancel"><span>Cancel</span></a>
</div>
</form>
In the javascript, I want to handle the fact that there might be multiple forms on the page, so I create a list of all the forms. For each form, I attach/render the reCAPTCHA logic, attaching my callback with the form passed as a parameter:
<script>
var $form_list = jQuery("form.custom-form-widget-form");
var onFormPageSubmit = function(token, $form ) {
console.log("Got here! ", token );
var field = $form.find('.g-recaptcha-response')[0];
field.value = token;
$form[0].submit();
};
var onloadCallback = function() {
$form_list.each( function() {
var $form = jQuery(this);
var $recaptcha = $form.find( ".g-recaptcha" );
if ( $recaptcha.length )
{
var recaptchaId = grecaptcha.render($recaptcha[0], {
'callback': function (token) { onFormPageSubmit(token, $form); },
'sitekey': "{$captcha_config.invisible_captcha_site_key}",
'size': 'invisible',
'badge': 'inline'
});
$form.data("recaptchaid", recaptchaId);
}
});
};
</script>
And just below that, I load the recaptcha/api.js file:
<script src="https://www.google.com/recaptcha/api.js?render=explicit&onload=onloadCallback"></script>
With some judicial 'console.log' statements, we get through all of the code EXCEPT for the callback (onFormPageSubmit). The "protected by reCAPTCHA" logo is there, but it seems that the form is just submitted, ignoring the reCAPTCHA call altogether.
All help appreciated.
Somewhere along the line, the validation function for the form was lost (it's in another file). The validation function was attached to the button, and it executed something like this:
$submit_button.on( 'click', function( event ) {
event.preventDefault();
// get the recaptchaid from form data
var $recaptcha_id = $form.data( "recaptchaid" );
if ( $recaptcha_id != undefined )
{
grecaptcha.execute($recaptcha_id);
}
} );
The "grecaptcha.execute" is the important thing - this is what triggers the actual reCAPTCHA call.

Dynamic Country - city select on form

newbie alert,
I am really enjoying perl Catalyst, however, i have googled and cant find a solution for Country - City dynamic selection. when i select a country from the dropdown, i would like the cities to change to that coutries cities only. How can i achieve this in Perl, Catalyst using HTML::FormHandler.
PS
The data is coming from mysql db with a one to many relatioship
has_field 'city_id' => (
label => 'City',
type => 'Select',
empty_select => 'Choose city',
required => 1,
required_message => 'Please enter city.',
);
has_field 'country_code' => (
label => 'Country',
type => 'Select',
empty_select => 'Choose country',
required => 1,
required_message => 'Please enter your country.',
);
has_field 'submit' => (
type => 'Submit',
value => 'Save',
element_class => ['btn']
);
sub options_country_code {
my $self = shift;
return unless $self->schema;
my #countries = $self->schema->resultset('Country')->all;
my #options = map { { value => $_->country_code, label => $_->country_name } } #countries;
unshift #options, { value => 0, label => 'Choose Country' };
return #options;
}
__PACKAGE__->meta->make_immutable;
1;
I found exactly what I was looking for, thank you for the effort, I appreciate it very much.
The solution I needed is here
I am using this code as my base:
<html>
<head>
<script type="text/javascript">
function setmenu2() {
var menu1 = document.getElementById('menu1');
var sel = menu1.options[menu1.selectedIndex].text;
var menu2 = document.getElementById('menu2');
if (sel == "Foo") {
menu2.innerHTML = "<option>Foo-1</option>"
+"<option>Foo-2</option>";
} else {
menu2.innerHTML = "<option>Bar-1</option>"
+"<option>Bar-2</option>"
+"<option>Bar-3</option>";
}
}
</script>
</head>
<body>
<select id="menu1" onchange="setmenu2()">
<option>please select...</option>
<option>Foo</option>
<option>Bar</option>
</select>
<select id="menu2">
<option>- ?? -</option>
</select>
</body>
</html>
So far this is what I have:
<script type="text/javascript">
function setcities() {
var country_select = document.getElementById('country_code');
var sel = country_select.options[country_select.selectedIndex].value;
var city_select = document.getElementById('city_id');
if (sel == "AFG") {
city_select.innerHTML = "<option value='1' id='city_id.1'>Kabul</option>"
+"<option value='2' id='city_id.2'> Qandahar</option>";
} else if (sel == "AGO"){
city_select.innerHTML = "<option value='56' id='city_id.1'>Luanda</option>"
+"<option value='57' id='city_id.2'>Huambo</option>"
+"<option value='58' id='city_id.3'>Lobito</option>";
} else {
city_select.innerHTML = "<option>nothing</option>";
}
}
</script>
<select id="country_code" onchange="setcities()">
<option value="" id="country_code.0">please select...</option>
<option value="AFG" id="country_code.1">Afghanistan</option>
<option value="AGO" id="country_code.2">Angola</option>
<option value="AIA" id="country_code.3">Anguilla</option>
</select>
<select id="city_id">
<option>- ?? -</option>
</select>

Form using dropdown doesn't work on Phalcon

I'm using the framework Phalcon. I'm trying to create a form to get a value (an ID called "idcliente") from a table (in mysql) called cliente, which has 2 columns: "idcliente" and "nombre". With this value I want to update a field (also "idcliente") on another table called Users.
My form is this:
class AsignarclienteForm extends Form{
public function initialize($entity = null, $options = null){
$idcliente = new Select('idcliente',[
Cliente::find(),
"useEmpty" => true,
"emptyText" => "Please select...",
"using" => ["idcliente", "nombre"],
]);
$idcliente->setLabel('ID Cliente');
$idcliente->addValidators(array(
new PresenceOf(array(
'message' => 'idcliente is required'
))
));
$this->add($idcliente);
}
}
And my controller:
public function asignarclienteAction(){
$auth = $this->session->get('auth');
$permiso = $auth['active'];
$id = $auth['id'];
if($permiso!='A'){return $this->forward('servicios/index');}
$form = new AsignarclienteForm;
if ($this->request->isPost()) {
$idcliente = $this->request->getPost('idcliente');
$sql = "UPDATE Users SET idcliente = ?0 WHERE id = ?1";
$this->modelsManager->executeQuery($sql, array(0 => $idcliente, 1 => $id));
return $this->forward('admin/usuarios');
}
$this->view->form = $form;
}
And my view:
<div class="panel-body">
{{ form('admin/asignarcliente/', 'id': 'asignarclienteForm', 'onbeforesubmit': 'return false') }}
<fieldset>
<div class="control-group">
{{ form.label('idcliente', ['class': 'control-label']) }}
<div class="controls">
{{ form.render('idcliente', ['class': 'form-control']) }}
</div>
</div>
<div class="form-actions">
{{ submit_button('Asignar', 'class': 'btn btn-primary', 'onclick': 'return SignUp.validate();') }}
</div>
</fieldset>
</form>
</div>
I got the following error in the web site:
ID Cliente
Catchable fatal error: Object of class Phalcon\Mvc\Model\Resultset\Simple could not be converted to string in C:\xampp\htdocs\OpinionZoom\cache\volt\c%%%%xampp%%htdocs%%opinionzoom%%app%%views%%admin%%asignarcliente.volt.php on line 31
Where line 31 is {{ form.render('idcliente', ['class': 'form-control']) }}
on my view
I haven't found enough documentation of how to create a form with select, despite I have created a lot of forms.
If someone could help me I would appreciate it a lot. Thanks.
Your element definition in your form Asignarclienteform is incorrect.
The first parameter of Select must be a string (the name of your element).
The second parameter takes the options of your select element.
// Select construct parameters
Select(string $name, [object | array $options], [array $attributes])
I moved idcliente out of the array into the first parameter position:
$idcliente = new Select('idcliente', Cliente::find(), [
"useEmpty" => true,
"emptyText" => "Please select...",
"using" => ["idcliente", "nombre"],
]);

Form text diappears and comeing ab up again

How do I do that in symfony?
http://dorward.me.uk/tmp/label-work/example.html
When I click into the input field username. The text disappears. If I don't enter nothing and click somewhere else the text is comeing up again. How do I do that in symofny in lib/forms/.
Thanks for an advice!
Craphunter
This isnt symfony - its javascript ... just take a look at the source (uses jQuery)
HTML:
<div class="slim-control">
<label for="username"> Username </label>
<input name="username" id="username">
</div>
<div class="slim-control">
<label for="password"> Password </label>
<input name="password" id="password" type="password">
</div>
JavaScript:
(function () {
var nonEmpty = "non-empty";
var inputs = jQuery('.slim-control input');
var setLabelStyle = function setLabelStyle () {
var label = jQuery(this);
if (label.val().length) {
label.addClass(nonEmpty);
} else {
label.removeClass(nonEmpty);
}
};
inputs.focus(function () {
jQuery(this).addClass(nonEmpty);
});
inputs.blur(setLabelStyle);
inputs.each(setLabelStyle);
}());
So if you want to do this - you would need to add the javascript to the template (indexSuccess.php) for example - you would probably need to modify the ids / classes to meet your local needs
Updated
You could create the following form - this would match the above form (untested):
$this->form = new sfForm();
$this->form->setWidgets(array(
'username' => new sfWidgetFormInputText(),
'password' => new sfWidgetFormInputPassword()
));
Creating forms (indeed all of Symfony) is very well documented here -> http://www.symfony-project.org/gentle-introduction/1_4/en/10-Forms
'input' => new sfWidgetFormInputText(array(), array('size' => '100', 'maxlength' => '255', 'value' => 'Some text', 'onblur' =>"if(this.value == '') { this.value='Some text'}", 'onfocus' =>"if (this.value == 'Some text') {this.value=''}")),
This is much shorter! Be careful that "Some text" is identical!
If you need to pass more, take a look to SetWidgetsHtml in Symfony form: (slide down)
http://www.symfony-project.org/forms/1_4/en/01-Form-Creation