I'm trying to dynamically generate a series of checkboxes in hbs. I have a bunch of arrays stored on a database and if the arrays contain the right numbers, I want a checkbox to be generated that has already been checked.
I've tried making a helper that just returns array.includes(num); and I've verified that everything works on that through logs, but if I plug my helper into an #if tag, I get one of many designer errors ranging from array.includes is not a function to ((depth0 && depth0.days_of_week) || alias2).call is not a function. I've even tried making a bunch of semi-static helpers so that I only need to pass one parameter instead of two and that didn't make any difference.
hbs.registerHelper('daysOfWeek', (array, dayNum) => {
return array.includes(dayNum);
});
...
<input type="checkbox" name="daysOfWeek" value="0" {{#if daysOfWeek (this.days_of_week 0)}}checked{{/if}}>Sunday
<input type="checkbox" name="daysOfWeek" value="1" {{#if daysOfWeek (this.days_of_week 1)}}checked{{/if}}>Monday
...
The syntax should be {{#if (daysOfWeek days_of_week 0)}}checked{{/if}}. Your helper function is correct.
<input type="checkbox" name="daysOfWeek" value="0" {{#if (daysOfWeek days_of_week 0)}}checked{{/if}}>Sunday
<input type="checkbox" name="daysOfWeek" value="1" {{#if (daysOfWeek days_of_week 1)}}checked{{/if}}>Monday
The if statement is checking the whole return of something, so in your case it is the helper function with two parameters: (daysOfWeek days_of_week 0).
Related
I have a app the creates forms dynamically. In the e2e tests, the e2e creates the form and after the test form will be deleted from the db.
This means I can not use class, ids, or data attribute values because their values are dynamically generated. ie: <div id="input_1642" class="input_1642">. Being the form is created by e2e and destroyed after the test is done, there is no way for me to know their values and they will not persist.
For the following html, in which the only unique value I really have is the required input in <span style="white-space: pre-wrap; overflow-wrap: break-word;">required input</span>
Using Playwright, and not being able to use class, id, or data attribute values, what is the cleanest way to grab (selector) the input so I can page.fill()?
I was hoping to avoid having using Xpath
<div id="input_1642" class="input_1642">
<div>
<div>
<div class="ant-row ant-form-item" style="row-gap: 0px;">
<div class="ant-col ant-form-item-label ant-form-item-label-left">
<label for="input_1642" class="ant-form-item-required" title="">
<span>
<span style="white-space: pre-wrap; overflow-wrap: break-word;">required input</span>
</span>
</label>
</div>
<div class="ant-col ant-form-item-control">
<div class="ant-form-item-control-input">
<div class="ant-form-item-control-input-content">
<span>
<span>
<input formbuilderhiddenfrom="" data-cy="form_item_input_1642_3" data-navigate="false" id="input_1642" class="ant-input align-input-items" type="text" value="">
<span></span>
How about you use a partial selector like this:
page.fill('[data-cy*="form_item_input_"]', 'some text')
To pinpoint the correct element, you can further use the Nth Selector
page.fill('[data-cy*="form_item_input_"] >> nth=0', 'some text')
According to the docs, you can find the element by the text of its label.
You have a label for that input. So you could try something like:
await page.locator('text=required input').fill('some text');
when I'm using the POST endpoint from Sveltekit, I get a "flat" object as output. How can I get a "structured" Object instead ?
Let's assume the following code:
index.svelte
<div class="container">
<form method="post">
<label for="firstname">Firstname</label>
<input type="text" name="firstname" />
<label for="lastname">Lastname</label>
<input type="text" name="lastname" />
<label for="dog">Dog 1</label>
<input type="text" name="dog" />
<label for="dog">Dog 2</label>
<input type="text" name="dog" />
<!-- ... -->
<button>Save</button>
</form>
</div>
index.js
export async function post({request}){
const data = Object.fromEntries(await request.formData());
console.log(data);
return{}
}
Ouput (what I'm calling "flat" object)
{ firstname: 'foo', lastname: 'bar', dog: 'teckel', dog: 'labrador' }
Instead of that output, how should I proceed to get the following one in my index.js
Expected output:
{
firstname: 'foo',
lastname: 'bar',
dogs: [ { dog: 'teckel' }, { dog: 'labrador' } ]
}
There are libraries that can perform a transform like this more or less automated. Some use conventions in the field names to parse the data into arrays and nested structures, others additionally use schemas to do type conversions or validation. E.g. to achieve an array of objects like this, one might set the names like this:
<label for="dog">Dog 1</label>
<input type="text" name="dogs[][dog]" />
<label for="dog">Dog 2</label>
<input type="text" name="dogs[][dog]" />
The [] Indicates that the field is part of an array, [dog] indicates that a property called dog is set on the element (.dog would also be reasonable).
So instead of calling Object.fromEntries you have to either parse the data yourself or find a library that does it for you. (Note that StackOverflow is not a place for library recommendations.)
Personally, I would avoid the synchronous form post and send JSON asynchronously instead, that way you can send in a fixed structure and receive that exact structure. Of course this requires binding/reading the form values yourself.
in the code below, I want to get checkbox value 'on/undefined' based on user selection and the value which I am passing (item._id) together in req.body. how do I do that?
<form action="/update" method="POST">
<div class="items">
<input type="checkbox" name="checkbox" value="<%= item._id%>" onChange=" this.form.submit()">
<p><%= item.title %></p>
</div>
</form>
Got the answer : Pass the additional attribute as hidden property.
I'm using Express.js and trying to get form data of a dropdown select element,
I tried with body-parser but what I get with eq.body.method_select is undefined.
I didn't find much info about how to do this on the web.
Here is my code html code:
<form action="url_analyse">
<div class="col-lg-6">
<div class="input-group">
<select class="custom-select mb-2 mr-sm-2 mb-sm-0" name="method_select" id="inlineFormCustomSelect">
<option value="5">Regular Search (Short)</option>
<option value="10">Intense Search (Long)</option>
<option value="20">Deep Search (Very Long)</option>
</select>
<input type="text" name="url_input" class="form-control" placeholder="Enter URL">
<span class="input-group-btn">
<button class="btn btn-secondary">Go!</button>
</span>
</div>
</div>
Here is my js code:
app.get('/url_analyse', function(req, res) {
console.log(req.body.method_select);
})
Hope you can help me with that.
Thank you.
There are two issues here:
You might want to explicitly add the leading forward slash: action="/url_analyse"
The default form submission HTTP method is GET, which means that form fields will be passed in the query string portion of the URL. This means you will instead need to access req.query to get at the form fields. You only need body-parser and req.body when you use POST and other methods (with the appropriate enctype) to submit your form.
I have a form that I am submitting using post. I can retrieve input values, however I also want to retrieve the class name or attribute of a div within a form.
html:
<form method='post' action='/formResult'>
<input type='text' name='someInput' />
<div class="stateAlpha" customAttr="alpha"></div> <!-- want 'alpha' -->
<button type="submit" class="btn btn-default">Submit</button>
</form>
node/express:
router.post('/formResult', function(req, res, next){
res.render('formResult', { someInput: req.body.someInput, someState: req.body.??? });
});
You'll need to intercept the submit event of the form, and put the class info into a hidden field. In pure JavaScript:
<form method='post' class='myForm' action='/formResult'>
<input type='text' name='someInput'>
<input type='hidden' name='state'>
<div class="stateAlpha" customAttr="alpha"></div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
<script>
document.querySelector('.myForm').addEventListener('submit', function(evt) {
var alpha = evt.target.querySelector('[customAttr="alpha"]');
var hiddenState = evt.target.querySelector('[name="state"]');
hiddenState.value = alpha.classList.join(' ');
});
</script>
Note that I added a class to the form, and used that to select the form; that's because you may have more than one form on the page, and you want to select the right one. Also note that inside the submit listener, I don't use document as the base of my selection, but evt.target; that's because you might have elements with customAttr='alpha' elsewhere in your document.
Once I have the div with the class you want to identify, I get the hidden input element, and set it's value property to the div's class list (remember any element can have more than one class, so classList is an array, which I just join using spaces).
If you're using jQuery, it gets a little shorter:
<form method='post' class='myForm' action='/formResult'>
<input type='text' name='someInput'>
<input type='hidden' name='state'>
<div class="stateAlpha" customAttr="alpha"></div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
<script>
$(document).ready(function() {
$('.myForm').on('submit', function() {
var $alpha = $(this).find('[customAttr="alpha"]');
$(this).find('[name="state"]')
.val($alpha.get(0).classList.join(' '));
});
});
</script>
The DOM is client-side and when you post the form only the values of the fields are posted, nothing else. To achieve what you are trying to do you can create a hidden field that stores the value of your class like this.
<input type="hidden" value="stateAlpha" name="myFieldName" />
This will then get sent in the form post.