Vuejs - How to submit only the visible elements in a single form (with Vuelidate) - vue.js

I have a form which includes some hidden and visible elements inside of it and I want to submit some of the elements without validating the hidden ones. At the top of my form there are three radio buttons and they control my form elements. When radiobutton1 selected, some of my form elements become visible and when another radio button is selected, there are some other form elements are visible and some of them are hidden. My question is how am I going to submit my form elements if only they are visible? All of the inputs should be in a single form so I am not allowed to separate them into different forms or different components. What I need to do is when I click the submit button of my form, the form should only submit the visible elements, and it shouldn't send me any error because I left some of the inputs empty (the hidden ones).
I also use Vuedalite so I couldn't figure out how to handle this problem. All of the input fields in the form has the required rule but this rule should be active ONLY IF THEY ARE VISIBLE.
Here is a little code.
<form #submit.prevent="submitForm">
<!-- Content Section -->
<div v-show="showContent">
<!-- Name Field-->
<div>
<div>
<label>Name</label>
<input v-model="name" :class="{'is-invalid' : $v.networkname2GHz.$error }" type="text"/>
<small class="errorMessage" v-if="!$v.name.required && $v.name.$dirty">Name field is required.</small>
</div>
</div>
<!-- Surname -->
<!-- Content Section -->
<div v-show="showContent">
<!-- Surname Field-->
<div>
<div>
<label>Surname </label>
<input v-model="surname" :class="{'is-invalid' : $v.surname.$error }" type="text"/>
<small class="errorMessage" v-if="!$v.surname.required && $v.surname.$dirty">Surnamefield is required.</small>
</div>
</div>
<div show="showContent">
<button type="submit">Save</button>
</div>
</form>
What I want to do is when the user selects the Name radio button only the Name field of the form will be visible and Surname will be hidden, I've done that, no problem. But how do I submit only the name field when surname still empty and has the required rule?

You can use v-if instead of v-show.
The main difference between the two is that, v-if - Only renders the element to the DOM if the expression passes. v-show - Renders all elements to the DOM and then uses the CSS display property to hide elements if the expression fails.

Related

How do I include the contents of a contenteditable element in a HTMX request?

I'd like to post the contents of a contenteditable field/div whenever it changes. hx-trigger="change" didn't trigger, but using hx-trigger="blur" is okay. How do I submit the value of the contenteditable div in the request?
<div id='parent-div'>
<div contenteditable='true'
hx-post="/update_db"
hx-trigger="blur"
hx-target="#parent-div"
hx-swap="outerHTML">
Hello, I am a content editable field
</div>
</div>
I don't believe htmx supports submitting contenteditable values out of the box. You'd probably need to mirror the content text within contenteditable to a a hidden input and move the hx attributes to the parent div.
You could use something like https://alpinejs.dev/ or htmx's companion https://hyperscript.org/
With hyperscript you could do it with something like this:
<div id='parent-div'
hx-post="/update_db"
hx-trigger="blur"
hx-target="#parent-div"
hx-swap="outerHTML">
<div id="editordiv" contenteditable='true'>
Hello, I am a content editable field
</div>
<input type="hidden" name="editor" _="on keyup from #editordiv put its innerHTML into me" />
</div>
I found an old reference from the htmx Discord that offers another way of doing this:
<form hx-post="/whatever"
hx-vals="javascript: editable:htmx.find('#myEditable').innerHTML"> ...

Vue - Form inside another form and submit event trigger

I have a form inside another form and I want to prevent default action for both forms on submit event:
Vue component:
<template>
<div v-show="isActive" #submit.prevent="onSubmit">
<slot :form="form"></slot>
</div>
</template>
Child:
<form method="POST" action="/update-user">
// form fields part 1
<form method="GET" action="/delete-user">
<button type="submit">
<span>{{ $is_deleted ? 'Cancel Delete' : 'Delete Account' }}</span>
</button>
</form>
// form fields part 2
<button type="submit">
<span>Update</span>
</button>
</form>
When I submit update-user form then the component onSubmit method is hit and prevents default action. However, when I hit delete-user form then the onSubmit method is not hit and the page gets reloaded.
If I get the second form outside of the first one, then it works.
How I can trigger onSubmit method for the second form?
No, This looks like nested form and it violates the spec as outlined in Prohibitions.
Form must not contain another form. I think you should design your app differently. May be two different forms. Or just use plain ajax request as its a vue app anyway?

Vue v-model not reactive with BS4 radio button group

I'm hoping I'm just missing something simple because I've been looking at this for too long, but I'm stumped.
I have a form with inputs bound to vuejs. I have a group of 2 radio buttons for selecting the "gender", and the binding is working perfectly. If I click on either of the radio buttons, I can see the data change in the vue component inspector.
But I'm trying to change the radio buttons to a Bootstrap 4 button group, and can't seem to get the v-model binding to work. No matter what I try, the gender_id in my vue data is not getting updated when I click either of the buttons in the button group.
The form input values are being fed in through vue component properties, but for simplicity, my data for the radio buttons/button group would look like this:
export default {
data() {
return {
genders: {
1: "Men's",
2: "Women's"
},
gender_id: {
type: Number,
default: null
}
}
}
}
Here is the code I have for the radio button version (which is working properly):
<div class="form-group">
<label>Gender:</label>
<div>
<div class="form-check form-check-inline" v-for="(gender, key) in genders" :key="key">
<input type="radio"
class="form-check-input"
name="gender_id"
:id="'gender_' + key"
:value="key"
v-model.number="gender_id">
<label class="form-check-label" :for="'gender_' + key">
{{ gender }}
</label>
</div>
</div>
</div>
Here is the button group version that is not properly binding to the gender_id data in vue.
<div class="form-group">
<label>Gender:</label>
<div>
<div class="btn-group btn-group-toggle" data-toggle="buttons">
<label class="btn btn-outline-secondary" v-for="(gender, key) in genders" :key="key">
<input type="radio"
class="btn-group-toggle"
name="gender_id"
:id="'gender_' + key"
:value="key"
autocomplete="off"
v-model.number="gender_id">
{{ gender }}
</label>
</div>
</div>
</div>
I've been using the following Boostrap 4 documentation to try to get this working.
https://getbootstrap.com/docs/4.0/components/buttons/#checkbox-and-radio-buttons
In the documentation for button groups they don't even include the value property of the radio inputs, whereas they do include it in the documentation for form radio buttons.
https://getbootstrap.com/docs/4.0/components/forms/#checkboxes-and-radios
Is this for simplicity or do button groups of radio buttons not even return the value of the checked button?
I see other threads stating that buttons groups are not meant to function as radio buttons, but if that's true for BS4, then why would Bootstrap have button groups with radio buttons as they do in their documentation referenced above? If you can't retrieve the checked state, then why not just use a <button> instead of <label><input type=radio></label>?
Any ideas as to what I'm doing wrong and/or not understanding correctly?
Thanks so much!
Thanks so much to #ebbishop for his helpful insights.
The issue was related to vue and bootstrap both trying to apply javascript to the buttons in the button group.
To get around this issue, it was as simple as removing data-toggle="buttons" from the button group. By removing the data-toggle attribute, the bootstrap js is not applied and vue can manage the button group.
Nothing is actually wrong your use of v-model here.
However: you must add the class "active" to the <label> that wraps each radio-button <input>.
See this fiddle for a working example.
Is that what you're after?

Using Selenium to verify presence of certain css computed elements for form fields

I would need a good way to verify error icon is shown for mandatory form fields when submitted with empty input using selenium 3 webdriverjs.
Below is part of DOM trace when error is thrown if mandatory field is left blank & form is submitted.
<div class="col-md-8 col-sm-8 col-xs-8 " style="display: inherit;">
<div class="vx_floatingLabel_complex vx_floatingLabel_active vx_has-
error-with-message ">
<label for="testerAccountData_phone">Telefone</label><div
class="vx_form-control" data-label-content="Telefonnummer" style="">
<input type="tel" maxlength="20" value="" autocomplete="off"
name="/testerAccountData/phoneNumber" id="testerAccountData_phone">
</div><span class="vx_form-control-error-icon icon icon-small icon-
critical-small"></span><span></span><span></span></div></div>
I am looking at validating multiple fields in the form,
Q: how do I use selenium to check if error icon appears for the field. i'm not sure if i can use getAttribute function, as error icon seems to be part of CSS element?
=> class="vx_form-control-error-icon icon icon-small icon-critical-small">
Once you confirm that you can select the element. Selenium has the element.isDisplayed() api that can help you determine if the element is visible
http://seleniumhq.github.io/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_WebElement.html
https://github.com/SeleniumHQ/selenium/blob/master/javascript/node/selenium-webdriver/lib/webdriver.js#L2160
//untested code:
driver.findElement(By.className('vx_form-control-error-icon')).isDisplayed();

Check box is not coming in Request.Form (NameValueCollection)

I create one Method in MVC 4.0 which taking the Request.Form (Namevaluecollection) in Form. I faced below issue in checkbox and radio button.
I added dynamically checkbox or radio button with below code, and I set the form value collection as "NameValueCollection formsCollection = Request.Form" in one of my controller method but that checkbox or radio button is not coming in "formsCollection.AllKeys" while other control like text box, text area, dropdown will work properly.
<form>
<div class="divLeft div1" id="div83ac0fad-41d5-40e5-99cd-f99ea8877b04">
<div class="control-group">
<label class="control-label">Checkbox 2</label>
<div class="controls">
<div id="cfCheckbox">
<label>Option 1</label>
<input type="checkbox" id="checkbox83ac0fad-41d5-40e5-99cd-f99ea8877b04" name="checkbox83ac0fad-41d5-40e5-99cd-f99ea8877b04">
<label>Option2</label>
<input type="checkbox" id="checkbox83ac0fad-41d5-40e5-99cd-f99ea8877b04" name="checkbox83ac0fad-41d5-40e5-99cd-f99ea8877b04">
</div>
</div>
</div>
</div>
</form>
You're having id="checkbox83ac0fad-41d5-40e5-99cd-f99ea8877b04" on both check-boxes and the main div. IDs in HTML are supposed to be unique.
Remove the IDs on the checkboxes. This should fix your problem.
FormsCollection uses Name for binding, not ID. So you don't really need your elements to have IDs.