Auto-appending URL parameters when using a custom hx-push-url value - htmx

I would like to push a custom URL but keep the parameters of the original request. Consider the following example
<script
src="https://unpkg.com/htmx.org#1.7.0"
integrity="sha384-EzBXYPt0/T6gxNp0nuPtLkmRpmDBbjg6WmCUZRLXBBwYYmwAUxzlSGej0ARHX0Bo"
crossorigin="anonymous">
</script>
<select id="select-number" name="number" hx-get="/debug" hx-push-url="/debug2" hx-target="#target">
<option value="1">1</option>
<option value="2">2</option>
</select>
<div id="target">
</div>
Let's say I serve this at http://127.0.0.1:7000/debug. If I select 2 in the select field this will trigger a request to /debug?number=2 as expected. However, the URL pushed to the browser is http://127.0.0.1:7000/debug2, not including the parameters.
I want the following pushed to the history: http://127.0.0.1:7000/debug2?number=2
This has also been discussed in htmx issue #653. From my understanding what I'm doing should work, but maybe I'm doing something wrong?

Related

Validate vue-select with vee-validate

I'm new to VueJS.
I'm trying to validate vue-select using vee-validate.
I've tried to validate it manually but of course its not a good approach.
So, I tried to use vuelidate but couldn't get the desired result.
Now i'm trying to use vee-validate. Validation works fine as desired
but the issue is v-model.
I created a global variable product, to calculate the length of array, and passed it in v-model. So that when Its empty product's value will be zero and i can return desired result from vee-validation.
Here's the .vue html part.
<ValidationObserver>
<form #submit.prevent="add">
<div class="row row-xs mx-0">
<label class="col-sm-4 form-control-label">
<span class="tx-danger">*</span> Add product(s):
</label>
<div class="col-sm-8 mg-t-10 mg-sm-t-0">
<ValidationProvider rules="required" v-slot="{ errors }">
<v-select
name="product"
placeholder="Add product(s)"
:options="availableProducts" <-- here is the options array
:reduce="name => name"
label="name"
#input="setSelected"
v-model="product" <-- this calculates length and pass it to vee **extends**
>
</v-select>
<div v-for="error in errors" :key="error"> {{ error }} </div>
</ValidationProvider>
</div>
<!-- col-8 -->
</div>
</form>
</ValidationObserver>
Here's validation.js file
import { extend } from 'vee-validate';
extend('required', value => {
console.log(value);
return value > 0;
});
I don't want this product value there. I know its not a good approach as well. I can't pass whole array to v-model because then I can't push options in it. I can't pass a single option to v-model as well then I won't get desired result.
All I want to validate v-select when options array is empty. Any suggestions?
Veevalidate doesn't validate directly on select elements. This is my workaround.
You should create a v-field "hidden" input and a visible select v-model element. The veevalidate will take place on the v-field.
Here is an example.
<v-field type="text" class="form-control disabled" name="expirationMonth" v-model="expirationMonth" :rules="isRequired" style="display:none;"></v-field>
<select v-model="expirationMonthUI" class="form-control" #click="synchExpirationMonthUI">
<option value="January">January</option>
<option value="February">February</option>
<option value="March">March</option>
<option value="April">April</option>
<option value="May">May</option>
<option value="June">June</option>
<option value="July">July</option>
<option value="August">August</option>
<option value="September">September</option>
<option value="October">October</option>
<option value="November">November</option>
<option value="December">December</option>
</select>
<error-message name="expirationMonth"></error-message>
Then add this to your methods to synch both together.
synchExpirationMonthUI() {
this.expirationMonth = this.expirationMonthUI;
}
I have found a way of doing this, with the Rendering Complex Fields with Scoped Slots from the Vee-Validate documentation. And using the bindings from Vue Select, it looks something like this:
<Field name="supportType" v-slot="{ field }" v-model="supportType">
<v-select :options="mediaTypes" label="name" :reduce="mediaType => mediaType.id" v-bind="field">
</v-select>
</Field>
As you can see, I am using here the name, v-slot and v-model for the Field from Vee-Validate, as normal. But the v-slot is very important as it carries the information from Vue Select to Vee-Validate, or at least I think so.
On the other hand I use the options, label, reduce and v-bind from Vue Select, these I use to handle the information. So with the :options I select my dataset, with label I tell Vue Select which label to select and show from the dataset, with :reduce I tell Vue Select what will be the value of the select tag and finally use v-bind to bind the value of the select to the Vee-Validate field. So the information used on the :reduce property will be displayed on the v-model="supportType".
I tested it with a button and it worked. And I liked this way so it is not that messy and I can use the validation and other things as usual.
Hope this helps anyone.
PD: I am using Vue 3, and the latest package of both Vee-Validate and Vue Select, as of today.

1 way binding fails after selecting option in vue.js

I'm trying to implement 1-way binding. What I want is that changing dropdown should affect the text in <p> and the text. Change tag should effect only text within <p>. But when I change the dropdown value, I lost the value within the <p> as well as within the tags
<span class="wt-select">
<select id="student_skill" v-model="selected">
<option v-for="(stored_skill, index) in stored_skills" :key="index.id" :value="stored_skill.id">{{stored_skill}} hours</option>
</select>
<p>{{ selected }}</p>
<input :value="selected" type="text" class="form-control" id="date_time">
</span>
How can I achieve this? I tried the following link, but still unable to achieve this one-way binding:
Vue.js get selected option on #change

VueJs DropDown Option Value is undefined when attempting to render the text value in a component v-for iteration

Take the following code which is essentially going to render a form stepper and for the purposes of simplifying my example I have included just one step:
<form-wizard :formdata="this.form_data">
<form-tab stepindex="1" title="Title of Tab" :selected="true">
<div class="col-md-11 col-lg-10">
<div class="form-group">
<label for="OptionType" class="sr-only">Option Type</label>
<select v-model="form_data.optionType" #change="onChangeOptionType" id="OptionType">
<option value=""/>
<option v-for="option in form_data.fees" v-bind:value="option.cost">
{{ option.text }}
</option>
</select>
</div>
</div>
</form-tab>
</form-wizard>
For reasons I cannot understand the values are bound to the select options as expected and without error however the option text throws an error in the browser console that I cannot seem to overcome.
Property or method "option" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.
It's like for some reason it is looking out to the wider scope for the option rather than the option in the v-for loop.
I'd appreciate any advice on how to correct this but also any help to try and understand why this is even the case.
If any additional information is required to help answer please let me know.
maybe the problem is v-bind:key on v-for
<select v-model="form_data.optionType" #change="onChangeOptionType" id="OptionType">
<option value=""/>
<option v-for="(option, i) in form_data.fees" v-bind:key="i" v-bind:value="option.cost">
{{ option.text }}
</option>
</select>

Why does "view-source:" show unrendered directives?

I have a static site with a couple of pages with vue.js.
The problem is when I open the source of a page "view-source:", I can see unrendered directives. I don't remember I had it on other sites. Am I missing something?
Name: ((contacts.name))
...
<colorpicker :color="contacts.color" v-model="contacts.color"></colorpicker>
...
<.. directive=`${something}`...>
edit, It won't help but here's another example.
I use (( delimiter insted of {{
This is how I see the page when viewing it through view-source:https://....:
<div class="control is-expanded">
<div class="select is-fullwidth">
<select v-model="k.s">
<option v-for="so in m.so" :value="so">(( so ))</option>
</select>
</div>
</div>
<colorpicker :color="k.c" v-model="k.c"></colorpicker>
Here's a screenshot of another part of the page:

Selenium element being blocked by non-existent element

I'm trying to run some Selenium tests in Java but some fields are being blocked by another one and aren't clickable. The problem is, that other field doesn't actually exist in the page source.
The error is: Element <select id="pets" class="sumo form-control SumoUnder" name="pets"> is not clickable at point (1025.833351135254,677.4000244140625) because another element <span> obscures it
There is no element that doesn't have other tags (id, class, etc.) with it. So what is this mysterious field?
Interestingly, if I try to access some other fields first, I get different obscuring fields, which ALSO don't exist on the page. Such as:
<p class="CaptionCont SelectBox">
Watching the test interactively doesn't help; there's nothing visible that's blocking the elements when the error's thrown.
Where are these phantom fields coming from, and how do I stop them from blocking my fields?
EDIT: I have found that these fields are being added by SumoSelect. They don't show up when you view the source of the page, but they're there if you save the page and open it locally.
<div class="col form-group">
<label for="pets">Pets</label>
<div class="SumoSelect sumo_pets" tabindex="0" role="button" aria-expanded="false">
<select id="pets" name="pets" class="sumo form-control SumoUnder" tabindex="-1">
<option value="">Select</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<p class="CaptionCont SelectBox" title="Select">
<span class="placeholder">Select</span>
<label><i></i></label>
</p>
<div class="optWrapper">
<ul class="options">
<li class="opt"><label>Select</label></li>
<li class="opt"><label>1</label></li>
<li class="opt"><label>2</label></li>
<li class="opt"><label>3</label></li>
</ul>
</div>
</div>
</div>
if not clickable, may be selectable.
Select pets = new Select(driver.findElement(By.id("pets")));
pets.selectByIndex(1);
When you are using a JS library to enhance the Select - you need to see the final DOM created by the JS library. In the case of SumoSelect - the CSS for the select box itself is:
<p class="CaptionCont SelectBox" title=" Volvo">
<span> Volvo</span>
<label><i></i></label>
</p>
See the span there? If you want to click the dropdown - you need to click that span.
Try to click using JavaScript Executor.
Reference Link:- http://learn-automation.com/click-in-selenium-webdriver-using-java-script/