I'm using laravel/phpunit tests and I would like to test a multidimensional form, this fields below works well except when I'm testing.
<input type="number" class="form-control" name="practice_options[{{$diff}}][tries]">
<input type="number" class="form-control" name="practice_options[{{$diff}}][questions][easy]">
<input type="number" class="form-control" name="practice_options[{{$diff}}][questions][easy]">
<input type="number" class="form-control" name="practice_options[{{$diff}}][questions][easy]">
<input type="number" class="form-control" name="practice_options[{{$diff}}][time_limit]">
This is my test:
$input = [
'practice_options[easy][tries]' => "1",
'practice_options[easy][questions][easy]' => "10",
'practice_options[easy][questions][medium]' => "7",
'practice_options[easy][questions][hard]' => "3",
'practice_options[easy][time_limit]' => "300"
];
$this->actingAsAdmin()
->visit('/courses/1/practice')
->submitForm(trans('admin::layout.save'), $input);
But dont works I get this error in tests
InvalidArgumentException: Unreachable field "practice_options"
Please help how to make test with multidimensional fields to pass
Thanks in advance!
I solved this, the crawler dont recognizes if you open a form in #section and close in another #section in same page.
In my specific case, because of layout I open a form in Header #section and my submit button was also in this section, and I create my fields in the below section and close the form.
I put all in the same section and worked, crawler founds all !
Related
I am new in SilverStripe. I want to create a custom HTML form in SilverStripe.
<form class="form-inline" $HelloForm.FormAttributes>
<p id="{$HelloForm.FormName}_success" class="message" style="">$HelloForm.Message</p>
<div class="form-group">
<label for="email">Email:</label>
<input type="text" class="form-control" id="email" placeholder="Enter email" name="email">
</div>
<div class="form-group">
<label for="pwd">Password:</label>
<input type="password" class="form-control" id="pwd" placeholder="Enter password" name="pwd">
</div>
<div class="checkbox">
</div>
$HelloForm.fields
<input type="hidden" value="{$AbsoluteLink}" name="redirectURL" class="action" id="{$HelloForm.FormName}_action_doSayHello"/>
And in my controller
public function HelloForm()
{
$form = Form::create(
$this,
'HelloForm'
);
$actions = new FieldList(
FormAction::create('doSayHello', 'Submit')->setAttribute('class', 'btn btn-success')
);
$form = new Form($this, 'HelloForm',$actions);
return $form;
}
public function doSayHello($data,$form)
{
$form->sessionMessage('thanks for contact us','good');
return $this->redirectBack();
//i am not getting success message after submit
}
Can I get a success message after submitting in this case?
When I use standard SilverStripe form it's working but when using custom HTML form like above I am stuck
You could submit the form via ajax, which would have many advantages.
The page does not have to refresh itself
You can animate the form after submitting, by sliding up or some kind of similar animation.
You can handle form states like success or error
Some example code (in jQuery):
let form = $('.form-inline');
$(form).ajaxSubmit({
success: function() {
$(form).slideUp();
$('#form-state').text("Successfully submitted form.");
}
})
i am new to this matter. I am trying to create a search form, that allows searching a database via http api and display the result on a website. The call requires authorization:
$headers = array ('headers' => array(
'Authorization' => 'bearer' . $token ,
'Content-type' => 'application/json',
'Accept' => 'application/json'));
My search form looks like this:
<form method="GET" accept="application/json" action="https://example.xx/api/v1/products?page=1&size=5&direction=asc&search=value">
<input type="text" name="search" size="40" maxlength="256" value="" placeholder="testsearch">
<input type="submit" name="search_button" value="Search">
</form>
When i enter something into the input field and hit the submit button, the browser displays:
{"error":"unauthorized","error_description":"Full authentication is required to access this resource"}
And in the browsers address field i see:
https://example.xx/api/v1/products?search=testvalue&search_button=Search
Obviously the authorisation is ignored and the url shows that i have left my website.
Do i have to make this work with an action="somephp.php"?
How can i authorize the call from the form and display the response in a website?
Hints much appreciated. theo
Thanks to the german wordpress forum, i found the answer –
The Form:
<form method="post" id="api-result-searchform" action="">
<input type="text" class="search" placeholder="<?php echo esc_attr_x( 'Author?', 'placeholder' ) ?>" value="" name="searchauthor" id="s" title="api-search" />
<input class="button"type="submit" name="search_button" value="Search">
</form>
And the call:
<?php
$searchterm = $_POST['searchauthor'];
$url = 'https://example.de/api/v1/product?search=ti=' . $searchterm;
$response = wp_remote_get($url, $headers);
//etc.
This works well.
I am using Tuple to pass two models inside the view like code given below.
#model Tuple<AdvanceSearchModel, List<SearchUserModel>>
<form role="search" method="post" action="/Public/AdvanceSearch">
<div class="form-group">
<label>Name</label>
<input name="FullNames" type="text" class="form-control" value=""/>
</div>
<div class="form-group">
<label>Product</label>
<input name="Products" type="text" class="form-control" value="" />
</div>
<div class="form-group">
<label>Location:</label>
<input name="Location" type="text" class="form-control" value="" />
</div>
<div class="form-group">
<label>State</label>
<input name="States" type="text" class="form-control" value="" />
</div>
<div class="form-group">
<label>Country</label>
<input name="Countries" type="text" class="form-control" value=""/>
</div>
</form>
All the name attributes inside inputs are of AdvanceSearchModel. How do I use tag helper such as asp-for when passing multiple model to the views containing one or multiple forms? Also how do I retain values of the form after submitting the form in above scenario?
As you can see in the source code of InputTagHelper
You can see it creates the name attribute based on the (lambda) expression in html-tag:asp-for.
what you need
You need a form name tag like this SearchUserModel[0].Location
Where:
SearchUserModel is the property name on the model which is in the controller method you post to
[0] is the index in the list
Location is the property on the iten in the list the SearchUserModel instance
My suggestion
Not to do
Extend the InputTagHelper and add a prefix option (which adds a prefex to the name).
Use a view model Not a tuple!
Create a partial view that only takes SearchUserModel + a prefix (like an int for which row in the list it is for example: usermodel[1])
In your view loop over the list and call the partial.
result
#model SearchUserModel
<input asp-for="Location" my-prefix="ListItem[#Model.Id]" class="form-control" />
Better longterm option
Make a HTML template on how SearchUserModel part of the form should look.
Do ajax call to get the data or put the data as json in your view. (or take step 3 from what not to do)
Generate the form with well structured javascript.
On submit Instead of submitting the form, parse the from to json and send this as json ajax call.
Why do i say this? It is easier to debug if you get weird databindings in your controller.
That said, option 1 is perfectly fine but it might lead to problems later, as it is very static template, you wont be able to add or remove rows easily.
References for proper html name tags for lists:
http://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx
How does MVC 4 List Model Binding work?
It is possible to use the basic types of field to create a multidimensional array name?
For example:
<input type="text" name="my_type[translations][name][de]">
<input type="text" name="my_type[translations][name][fr]">
You can use ColectionType. But then you will probably need to change something about how you're using input names like here name="my_type[translations][name][fr]", maybe name="my_type[translations][nameFr]". Using it, your inputs will look like
<input type="text" name="my_type[translations][0][nameDe]">
<input type="text" name="my_type[translations][0][nameFr]">
<input type="text" name="my_type[translations][1][nameDe]">
<input type="text" name="my_type[translations][1][nameFr]">
Here I also presume that you have Translation entity which would have nameDe and nameFr properties.
Problem solved after I found an other template. Seems the previous one is incompatible.
I'm using the Plugin Foxycomplete (advanced autocomplete search with images) - more specifically: I want to use it. I installed and enabled it. The developer explains one step like this:
Enter the ID of the Form Input Field WITHOUT THE '#' on which you wish to apply the Autocomplete functionaliy. Defaults to the Regular "s".
I've even looked at the file foxycomplete.js, but I don't get it:
(function($) {
$(document).ready(function() {
var inputField = site_data.inputField;
var inputWidth = 0;
var absPath = "";
if(site_data.inputField == ""){
inputField = "s";
}
After this I took a look at the search form with firebug and this is the HTML-code:
<form action="http://localhost/sites/wordpress/" class="searchform" method="get">
<input type="text" value="" name="s" class="field">
<input type="submit" value="" name="submit" class="submit">
</form>
Now I'm assuming that I have to change class = "field" to id = "s", but I also do not know in which document I find the HTML part, I am a little stuck. If I do the change in firebug, it doesn't work.
all you need to do is to add following to your "input type" - name="s", id="s". This worked for me on a Canvas theme, by woothemes, and should be cool with any other
as an example for your code:
<input type="text" name="s" id="s" value="" class="field">
edit: search form code location really different to each theme template. but in most cases it's in header or sidebar.