Add unnamed field to form. Mechanize Ruby - mechanize-ruby

I am struggling to add fields to a form, because Mechanize doesn't detect the fields.
I have 3 forms and I managed to select the correct form.
Entering p site.forms gives the following:
=> [#<Mechanize::Form
{name "userloginform"}
{method "POST"}
{action "/user?destination="}
{fields
[text:0xc01f34 type: text name: name value: ]
[field:0xc01cf0 type: password name: pass value: ]
[hidden:0xc01ad4 type: hidden name: url value: en/Results+Statistics]
[hidden:0xc01930 type: hidden name: form_id value: user_login]}
{radiobuttons}
{checkboxes}
{file_uploads}
{buttons [submit:0xc017c8 type: submit name: op value: Login]}>
, #<Mechanize::Form
{name "searchFromBlock"}
{method "GET"}
{action ""}
{fields
[text:0xc04964 type: text name: queryString value: Search]
[hidden:0xc044b4 type: hidden name: num value: 10]
[hidden:0xc09f68 type: hidden name: pagenum value: 1]
[hidden:0xc09ce8 type: hidden name: start value: 1]
[hidden:0xc09ae0 type: hidden name: lang value: en]
[hidden:0xc097e8 type: hidden name: content value: all]}
{radiobuttons}
{checkboxes}
{file_uploads}
{buttons [submit:0xc046f8 type: submit name: search value: ]}>
, #<Mechanize::Form
{name nil}
{method "GET"}
{action ""}
**{fields}**
{radiobuttons}
{checkboxes}
{file_uploads}
{buttons}>}>
]
I select the last form (which is my target), by: form = site.form[2]
The problem is that this form doesn't contain any fields according to Mechanize, but in reality it does contain another 3 fields. I want to manipulate these, but before I can do that I need to add the fields to the form object.
An example of such a field is:
<select id="season" class="w_label_resul fonts12" style="display: none" size="7">
<option title="1949" value="1949"> … </option>
<option title="1950" value="1950"> …</option>
<option title="1951" value="1951"> … </option>
<option title="2012" value="2012"> … </option>
<option title="2013" value="2013"> … </option>
<option class="selected" selected="" title="2014" value="2014"> … </option>
</select>
As you see, it has no 'name', so I can't use the add_field! method for Mechanize::form,
because that takes as first argument the field_name, which is not present.
Meaning it isn't properly parsed by Nokogiri?
Is there any other way to add a field manually or am I overlooking something?

I found out that the webpage is generated by javascript.
This is probably why the form doesn't work.
Reading through the java code, I found out how the weblink gets build up by the options you select. Using Nokogiri to iterate over these options, building the link and downloading the html source code, I was able to navigate to the places I wanted.

Related

ORO CRM datagrid refresh after inline edit failed by missing parameter

I have a datagrid:
datagrids:
gates-under-location-grid:
inline_editing:
enable: true
extended_entity_name: Entity\Gate
source:
type: orm
query:
select:
- g
- l
- ancestor.id as ancestorId
- ancestor.name as ancestorName
from:
- { table: Entity\Gate, alias: g }
join:
left:
- { join: g.locations, alias: l }
inner:
- { join: Entity\LocationClosure, alias: lc, conditionType: WITH, condition: 'l.id=lc.descendant' }
- { join: Entity\Location, alias: ancestor, conditionType: WITH, condition: 'ancestor=:rootLocation'}
where:
and:
- lc.ancestor=:rootLocation
bind_parameters:
rootLocation: ~
hints:
- HINT_TRANSLATABLE
columns:
name:
label: 'gate.datagrid.field.name'
align: left
locations:
label: 'gate.datagrid.field.locations'
align: left
data_name: locations
data: locations
type: twig
template: Partials/Datagrid/Gate:locations_cell_in_gate_under_location_grid.html.twig
frontend_type: html
inline_editing:
behaviour: enable_selected
editor:
view: oroform/js/app/views/editor/related-id-select-editor-view
view_options:
value_field_name: locations.name
placeholder: 'placeholder'
autocomplete_api_accessor:
class: oroentity/js/tools/entity-select-search-api-accessor
entity_name: Entity\Location
search_handler_name: locations
value_field_name: id
field_name: name
label_field_name: name
properties:
id: ~
view_link:
type: url
route: gate_view
params: [ id ]
update_link:
type: url
route: gate_update
params: [ id ]
sorters:
columns:
name: { data_name: g.name }
default:
name: ASC
filters:
columns:
name:
type: string
data_name: g.name
actions:
view:
type: navigate
label: 'common.grid.details'
link: view_link
icon: eye
update:
type: navigate
label: 'common.grid.edit'
icon: edit
link: update_link
options:
entityHint: 'gate.datagrid.entityhint'
export: true
entity_pagination: true
routerEnabled: false
The location cell editor template is in the locations_cell_in_gate_under_location_grid.html file:
{% import 'OroUIBundle::macros.html.twig' as UI %}
<span class="inline-actions-element">
{% for location in value %}
<span class="tags-container">
<a href="#" title="{{ location.name }}" class="tags-container__tag-entry">
<span>
{{ location.name }}
</span>
</a>
</span>
{% endfor %}
<span class="inline-actions-element_actions inline-actions-element_wrapper" data-role="container">
{{ UI.clientButton({
'dataUrl': path('gate_locations_update',
{
'gateId': record.rootEntity.id,
'locationId': record.getValue('ancestorId')
}),
'aCss': 'inline-actions-btn inline-actions-btn--size-s',
'iCss': 'fa-pencil',
'dataId': record.rootEntity.id,
'title' : 'Edit'|trans,
'label' : 'Edit'|trans,
'widget' : {
'type' : 'dialog',
'multiple' : false,
'reload-grid-name' : 'gates-under-location-grid',
'options' : {
'alias': 'gate_locations_update_dialog',
'stateEnabled': false,
'dialogOptions' : {
'title' : 'gate.datagrid.under_location.locations_edit_widget.title'|trans,
'allowMaximize': false,
'allowMinimize': false,
'width': 600,
'modal': true,
},
},
},
}) }}
</span>
Controller action is the following:
/**
* Shows editForm, or updates Gate with given ID
*
* #Route("/locations-edit/gate/{gateId}/location/{locationId}", name="gate_locations_update", requirements={"gateId"="\d+","locationId"="\d+"})
* #Template("Gate:locations_update.html.twig")
* #ParamConverter("gate", class="Entity\Gate", options={"id" = "gateId"})
* #ParamConverter("location", class="Entity\Location", options={"id" = "locationId"})
*
* #param Request $request
* #param Gate $gate
* #param Location $location
*
* #return array|RedirectResponse
*/
public function updateLocationsAction(Request $request, Gate $gate, Location $location)
{
$form = $this->get('form.factory')
->create(GateLocationsType::class, $gate, ['attr' => ['rootLocation' => $location]]);
return $this->get('oro_form.update_handler')
->update(
$gate,
$form,
$this->get('translator')->trans('common.processes.successful_saved'),
$request
);
}
I wanted to refresh the cell after inline edit, but since i didn't find any chance, it would be good to refresh whole datagrid.
The problem is with this solution, after cell data stored, i got the Data loading failed, try reloading the page. If the issue appears again please contact your administrator. message, and it's logged in the log file:
request.CRITICAL: Uncaught PHP Exception Oro\Bundle\DataGridBundle\Exception\InvalidArgumentException: "Cannot bind datasource parameter "rootLocation", there is no datagrid parameter with path "rootLocation"." at vendor/oro/platform/src/Oro/Bundle/DataGridBundle/Datasource/Orm/ParameterBinder.php line 164 {"exception":"[object] (Oro\\Bundle\\DataGridBundle\\Exception\\InvalidArgumentException(code: 0): Cannot bind datasource parameter \"rootLocation\", there is no datagrid parameter with path \"rootLocation\". at app/vendor/oro/platform/src/Oro/Bundle/DataGridBundle/Datasource/Orm/ParameterBinder.php:164, Symfony\\Component\\PropertyAccess\\Exception\\NoSuchPropertyException(code: 0): The key \"rootLocation\" does exist in an array. at app/vendor/oro/platform/src/Oro/Component/PropertyAccess/PropertyAccessor.php:435)"} []
I tried to add the parameters, but these efforts didn't affected on the error.
Could somebody help, how to pass the rootLocation parameter for the refresh?
Thanks in advance!
A custom controller is not a recommended way to handle the inline editing in the datagrid.
Please follow the official documentation on Creating editable data grid cells in OroPlatform applications.
Also, there is a general reference on inline editing in the OroPlatform datagrids, where you can find the documentation about all the existing inline editor options. You can use one of them, instead of implementing the custom one, or you can use it as a base for creating your own editor.

Dropdown created by EasyAdmin Bundle not closing on select

I am creating a backend to my Symfony4.2 site using the easyadmin bundle. in the new/edit form created for my entities it creates a dropdown to select from. However, in chrome and firefox these dropdowns are not behaving as expected. When I click on them it shows the options but it does not close if I select an option or click away from the dropdown menu. It works okay on Safari and Edge.
Here is the easyadmin.yaml
easy_admin:
#Global Settings
site_name: 'Physics Quiz SIte'
design:
assets:
favicon: '/build/images/favicon.ba133a8b.ico'
# this is the default form theme used by backends
form_theme: '#EasyAdmin/form/bootstrap_4.html.twig'
# these custom templates are applied to all entities
brand_color: '#1ABC9C'
menu:
- { label: 'Public Homepage', route: 'homepage', icon: 'home' }
- { entity: 'User', icon: 'user' }
- { entity: 'QuestionType' }
- { entity: 'Question' }
- { entity: 'Quiz' }
show:
max_results: 10
list:
actions:
- { name: 'edit', icon: 'pencil'}
- { name: 'delete', icon: 'trash'}
# allow deleting multiple items at once ...
batch_actions: ['delete']
# List the entity class name you want to manage
entities:
Quiz:
class: App\Entity\Quiz
form:
fields:
- property: 'quizname'
label: 'Quiz Name'
- property: 'course'
type: 'entity'
type_options:
expanded: false
multiple: false
This is the relevant page source that is created:
<div class="col-12 ">
<div class="form-group field-entity">
<label class="form-control-label required" for="quiz_course">Course</label>
<div class="form-widget">
<select id="quiz_course" name="quiz[course]" data-widget="select2" class="form-control">
<option value="1">Year 10 Physics</option>
<option value="2">Year 11 Physics</option>
</select>
</div>
</div>
</div>
and here are the scripts that may be relevant.
<script src="/bundles/easyadmin/select2/i18n/en.js"></script>
<script type="text/javascript">
$(function() {
// Select2 widget is only enabled for the <select> elements which
// explicitly ask for it
function init() {
$('form select[data-widget="select2"]').select2({
theme: 'bootstrap',
language: 'en'
});
}
$(document).on('easyadmin.collection.item-added', init);
init();
});
</script>
Here is a picture of the rendered dropdown:
This was a bug introduced in version 2.1.2.
https://github.com/EasyCorp/EasyAdminBundle/issues/2715
There was a new release 2.1.3 that fixes the problem.

How do I add a <select> input to the product variantForm in Reaction Commerce?

How do I get a <select> drop-down menu in the product varientForm?
Something like what we see here:
To accomplish adding a <select> to variantForm as seen above we need to edit or extend three files, variantForm.html, variantForm.js and the products.js schema:
reaction/imports/plugins/included/product-variant/client/templates/products/productDetail/variants/variantForm/variantForm.html
reaction/imports/plugins/included/product-variant/client/templates/products/productDetail/variants/variantForm/variantForm.js
reaction/lib/collections/schemas/products.js
In the AutoForm live example of <select> we see a schema that looks like this:
{
typeTest: {
type: String,
optional: true,
autoform: {
type: "select",
options: function () {
return [
{label: "2013", value: 2013},
{label: "2014", value: 2014},
{label: "2015", value: 2015}
];
}
}
}
}
and a Blaze template HTML that looks like this:
{{#autoForm id="types2" schema=typesSchema2}}
{{> afFormGroup name="typeTest" type="select" options=optionsHelper}}
<div class="form-group">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
{{/autoForm}}
Step 1
Edit/extend products.js schema file adding your select except we only need to add these parts:
typeTest: {
type: String,
optional: true,
autoform: {
type: "select"
}
},
Reaction Commerce ignores the optionHelper function from AutoForm as we see in the above example. I keep the autoform: { type: "select" } just to express intension. For a real-world example of a product.js schema modified this way see here.
Step 2
Add your helper function to variantForm.js that returns your selection's options object. Inside Template.variantForm.helpers({}) add:
variantTypeOptions: function (){
return [
{label: "Default", value: 2013},
{label: "Height & Weight", value: "Height & Weight"}
];
},
Nice and simple (and similar to the AutoForm example), these become the selection options we see in the screenshot above. Real-world example here.
Step 3
Final step. Let's lastly add the Blaze template HTML to variantForm.html:
<div class="form-group{{#if afFieldIsInvalid name='variantType'}} has-error{{/if}}">
<label class="control-label">{{afFieldLabelText name='variantType'}}</label>
{{>afFieldInput name='variantType' type="select" options=variantTypeOptions}}
{{#if afFieldIsInvalid name='variantType'}}
<span class="help-block">{{afFieldMessage name='variantType'}}</span>
{{/if}}
</div>
With our focus on:
{{>afFieldInput name='variantType' type="select" options=variantTypeOptions}}
Real-world example here.
Closing Remarks
You may need to do a rc reset for the changes to the schema to take effect, but WARNING, this will wipe your local development database. See the note in the RC Docs about having to do frequent resets in the "Creating a Plugin" article.

Inserting a file into an array in Meteor using aldeed:autoform, cfs:autoform and the update-pushArray type

I'd like to build an array of uploaded files in each document in my collection named Modules. I'm using the following packages:
aldeed:autoform
aldeed:collection2
cfs:standard-packages
cfs:gridfs
cfs:autoform
Collection and Schema (relevant parts):
Modules = new Mongo.Collection('modules');
Modules.attachSchema (new SimpleSchema({
slides: {
type: Array,
optional: true
},
'slides.$': {
type: Object
},
'slides.$.fileId': {
type: String,
label: "Image File"
},
'slides.$.time': {
type: Number,
label: "Time in Seconds"
}
}));
FileStore = new FS.Collection("fileStore", {
stores: [new FS.Store.GridFS("fileStore")]
});
FileStore.allow({
download: function() {
return true;
},
fetch: null
});
In the HTML Template:
{{#autoForm collection="Modules" scope="slides" id="addSlideForm" type="update-pushArray" doc=this}}
<fieldset>
{{> afQuickField name="time" type="number"}}
{{> afQuickField name="fileId" type="cfs-file" collection="fileStore"}}
</fieldset>
<button type="submit" class="btn btn-primary" >Add Slide</button>
{{/autoForm}}
When I hit the submit button, an element is pushed into the array as expected. The time value is correct, but under fileId there is only dummyId instead of the expected _id from fileStore.
In other parts of the application that do not involve nested arrays, uploading files works as expected. In other parts of the application that do not involve uploading files, the update-pushArray form works as expected. The complication is with combining the two.
Am I doing this incorrectly? Or is cfs:autoform just not compatible with the update-pushArray form type?
To use CFS your #autoform type must be either "insert" or "method", check cfs documentation for more info.
Hope it helps!

radio click on text in an easier way

I use an theme, which can provide my an beautiful UI
The code is sort of dirty, because I need to specify each input an unique id,
Is there any alternative way ?
I wrote it in Haml
%input.ace{id: "radio_field_1", name: "radio_field[]", type: "radio", value: "1"}/
%label.lbl{for: "radio_field_1"}
radio option 1
%input.ace{id: "radio_field_2",name: "radio_field[]", type: "radio", value: "2"}/
%label.lbl{for: "radio_field_2"} radio option 2
%input.ace{id: "radio_field_3",name: "radio_field[]", type: "radio", value: "3"}/
%label.lbl{for: "radio_field_3"} radio option 3
The HTML output
<input class="ace" id="radio_field_1" name="radio_field[]" type="radio" value="1">
<label class="lbl" for="radio_field_1">
radio option 1
</label>
You should be using a rails form helper, not pure HTML, to create your form:
- form_tag "/some_path" do
- 3..times do |i|
= radio_button_tag 'radio_field', i, id: "radio_field_#{i}"
= label_tag 'radio_field, 'radio button #{i}'
This should work - will help further if it doesn't

Resources