All Browsers except Firefox don't react to jQuery .click() - html

I have the following HTML/Twig structure
<select name="herstellerSelect" class="categoryElement" id="herstellerDropdown" style="display: block;">
<option class="preselect" value="" style="display: block;">Hersteller wählen</option>
{{ _self.cpitems0(categories.categories, categories.categories_info, parts, oop_display, oop_opened) }}
</select>
The Twig macro "cpitems0" generates elements for the
This is the jQuery Code that should, amongst other things, output a text to the console once children (<option> elements of the <select>) are clicked.
$(document).ready(function() {
console.log('CATEGORY SELECTOR TEST');
$("#herstellerDropdown").children().click(function(e) {
e.preventDefault();
console.log('CATEGORY SELECTOR TEST 2');
...
I have also tried
$(document).ready(function() {
console.log('CATEGORY SELECTOR TEST');
$("#herstellerDropdown").on('click', '> *', function(e) {
e.preventDefault();
console.log('CATEGORY SELECTOR TEST 2');
...
Only Firefox (private mode and cleared browser cache) displays the second console.log output, all the other tested Browsers (Brave, Chromium, Opera Developer in private mode with cleared Browser cache on Ubuntu 20.4) only display the first console.log output
Does anyone know why this happens?
Upate 14.10.2021 14:20 -> I have to use $("#herstellerDropdown").on("change" ... ) instead of .$("#herstellerDropdown").click because it's a element.
Generally, I have to use "AJAX Cascading Dropdowns" for what should be realized. I thought I could avoid AJAX and load the server generated content into the DOM and copy the respective elements with $("selectElement").html( elements) but I guess that results in poor performance and bad design so I have to go with the Cascading Dropdowns!

Use on("change" instead of click
Options do not need ID
Why display:block?
Why preventDefault() ?
This works in Chrom(e/ium) and Fx
$(function() {
$("#herstellerDropdown").on("change", function(e) {
console.log(this.value)
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select name="herstellerSelect" class="categoryElement" id="herstellerDropdown">
<option class="preselect" value="" style="display: block;">Hersteller wählen</option>
<option data-val-one="Key0" data-val-two="" data-val-three="" value="entry0">categories_info[keyZero].elementid 0</option>
<option data-val-one="Key1" data-val-two="" data-val-three="" value="entry1">categories_info[keyZero].elementid 1</option>
<option data-val-one="Key2" data-val-two="" data-val-three="" value="entry2">categories_info[keyZero].elementid 2</option>
</select>

Related

Using jquery load function in combination with forms

Currently developing a new website and looking to use jQuery's load() function to load content from different html pages into my main page.
load() works fine. Here's my current code.
Main.html page in which content is loaded:
<div id="answer"></div>
Javascript with the load() function:
$(document).ready(function() {
$("#answer").load( "game1content.html #p1Answer");
game1content.html content to load:
<div id="p1Answer">
<p>Some text</p>
<form id="answer1Form">
<select name="answer1" id="answer1">
<option value=""></option>
<option value="1">Website 1</option>
<option value="2">Website 2</option>
<option value="3">Website 3</option>
<option value="4">Website 4</option>
</select>
<button id="submitButton">SUBMIT</button>
</form>
</div>
So it loads html correctly into the answer div. Perfect.
Now the challenge is that when I submit the form that's loaded, it refreshes the page. When I have the game1content content in the main.html file, instead of using the load() it doesn't reload and works fine. But if I use the load() function, it does reload and also changes the url.
Here's my function on submit:
$( "#answer1Form" ).submit(function(e) {
e.preventDefault();
console.log ("clicked");
});
I've tried Googling this issue, but can't find much. Also, tried changing .submit to onclick etc, but same result. Any ideas?
That's because when you call .load, it fetch the page content and adds DOM elements but not bind them to events, so the form behave like it should, refresh the page.
In order to prevent the form from refreshing you should listen to .submit() exactly like you do in game1content.html after the DOM elements are added.
Like this:
$("#answer").load( "game1content.html #p1Answer", function() {
$( "#answer1Form" ).submit(function(e) {
e.preventDefault();
console.log("clicked");
});
});

How to use "invalid-feedback" class with selectpicker from Bootstrap-Select?

I'm using Bootstrap to do some form validation on my web app. With a normal select menu, it would be really easy to have an error message pop-up when the field is invalid:
<select class="someClass" required>
<option value="">Select an option</option>
<option>foo</option>
<option>bar</option>
</select>
<div class="invalid-feedback">Please make a selection.</div>
However, I'm using Bootstrap-Select's "selectpicker" class, and the "invalid-feedback" message in the div no longer works. Is there anyway to force Bootstrap-Select to recognize the "invalid-feedback" class or am I going to have to go about this a different way?
I figured out how to do this, and more generally this is an answer for anytime you have to "manually" force an error to work with Bootstrap's native validation system. It's really hacky, but I couldn't find anything else that works.
Say you have a "selectpicker" that looks like this:
<select id="mySelect" class="selectpicker" required>
<option value="">Select an option</option>
<option>foo</option>
<option>bar</option>
</select>
<div id="error" class="invalid-feedback">Please make a selection.</div>
The error message "Please make a selection" will not show, even if the select element is invalid; it will show, however, if it also has the "d-block" class:
<div id="error" class="invalid-feedback d-block">Please make a selection.</div>
So to manually force errors, you have to use JavaScript to check for the ":invalid" CSS pseudo-class; if it has this pseudo-class, then you add the "d-block" class to your div to show the error. You can use the matches() method and classList.add():
var selector = document.getElementById("mySelect");
var errorMsg = document.getElementById("error");
if(selector.matches(":invalid"))
{
errorMsg.classList.add("d-block");
}
You do this to add the message and you can remove it by checking for ":valid" and removing "d-block" from the classList.
I had multiple versions of the bootstrap-select elements in one of my forms and was having a really hard time getting this to work. The method below won't show the checkmark or x on the input, but it will show the invalid-feedback and valid-feedback boxes properly.
Using the advice from secretagentmango's answer, you can create a function that loops through all of your inputs with the "selectpicker" class, grab their parent form-group element, and then find the children "valid-feedback" and "invalid-feedback" elements
to add or remove the d-block class and hide/show them.
function bsSelectValidation() {
if ($("#myForm").hasClass('was-validated')) {
$(".selectpicker").each(function (i, el) {
if ($(el).is(":invalid")) {
$(el).closest(".form-group").find(".valid-feedback").removeClass("d-block");
$(el).closest(".form-group").find(".invalid-feedback").addClass("d-block");
}
else {
$(el).closest(".form-group").find(".invalid-feedback").removeClass("d-block");
$(el).closest(".form-group").find(".valid-feedback").addClass("d-block");
}
});
}
}
Now you need to run this function after form submit, and you can add it directly to the sample code from the Bootstrap Docs:
(function () {
'use strict';
window.addEventListener('load', function () {
// Fetch all the forms we want to apply custom Bootstrap validation styles to
var forms = document.getElementsByClassName('needs-validation');
// Loop over them and prevent submission
var validation = Array.prototype.filter.call(forms, function (form) {
form.addEventListener('submit', function (event) {
if (form.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add('was-validated');
bsSelectValidation();
}, false);
});
}, false);
})();
The only thing different in the above code from bootstrap's sample is the call to our new function, "bsSelectValidation".
Now you need to listen for changes in the form to automatically update the d-block classes and fix the valid/invalid messages as people make changes to the form:
$('#myForm').change(bsSelectValidation);
Now your select menus should properly show the valid-feedback and invalid-feedback divs on form submit or change.
I found that if I simply remove the value="" part of the "option" element, then the validation message shows properly. That is, if I don't select anything from the dropdown, the my "invalid-feedback" message shows up. When I select something, it goes away and I can proceed further. It's worth a try if you haven't tried it.
My first "option" is simply this: <option>(select)</option> -- no 'value' clause is present.
Hope this helps.

protractor testing on multi select giving 'Element not visible' error

I have the following html code with a multiselect element. On running tests with protractor to select the options, I get the error as 'Element not visible'.
<div id="one" class="class1">
<select id="select1" style="width: 70%;" class="multiselect" multiple="multiple" ng-model="formData.abcqw">
<option value="abc">ABC</option>
<option value="xyz">XYZ</option>
<option value="pqr">PQR</option>
</select>
</div>
protractor code :
browser.actions().
mouseMove(element(by.className("multiselect"))).click().perform();
element(by.model("formData.abcqw")).sendKeys("abc");
Any help is appreciated.
It's pretty much evident from the HTML which you have shared that the <select> tag is an AngularJS element, so we have to induce wait i.e. WebDriverWait as follows for the element to be selectable:
var EC = protractor.ExpectedConditions;
// Waits for the element with id 'select1' to be selected.
browser.wait(EC.elementToBeSelected($('#select1')), 5000);
I also think that it is a wait issue.
Whenever you see this "element not visible error" you can add
browser.sleep(5000);
before the click statement and try again
if that doesn't work try below.
This when we intentionally want to click an hidden element. So this should work
var elm = element(by.className("multiselect "));
browser.executeScript("arguments[0].click();", elm.getWebElement());
browser.sleep(2000);
element(by.model("formData.abcqw")).sendKeys("abc");
Try the following code, I replicated the same in my local and verified the below code it works fine:
var EC = protractor.ExpectedConditions;
var multiSelectElement = element(by.model('formData.abcqw');
browser.wait(EC.visibilityOf(multiSelectElement))).then(function() {
browser.wait(EC.elementToBeClickable(multiSelectElement.element(by.cssContainingText('option', 'ABC'))))).then(function() {
multiSelectElement.element(by.cssContainingText('option', 'ABC')).click();
});
});

HTML 5 Datalist - How to autoselect if only one option is available

User types into the input box with datalist attached, one option is displayed that they can click on to select. How can I auto select that single option?
Okay so datalist is an HTML5 element that allows for a native autocomplete feature on most modern browsers. That being said it does not provide the ability to set a default or selected option. Additionally it does not have events available so you need to do it using standard events on your elements.
Example
$(document).ready(function () {
var datalist = $('#someCountries');
var opts = datalist.find('option');
console.log(opts.val());
console.log(opts.length);
function checkOpts() {
if (opts.length === 1) {
$('#country').val(opts.val());
}
}
$('#country').on('focusin', checkOpts);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="country" list="someCountries" />
<datalist id="someCountries">
<option label="United Stated" value="USA"></option>
</datalist>
You will probably need to modify the focusin event to something more appropriate for your situation, but this should get you on your way.

Html DropDownList not generating events

In my web page I use something like this, but when a option is selected, onchange is not fired. I don't know where I have made a mistake. Actually my requirements is that I need to fetch location details based on the city selected, but it is not working here. Is there any other better way to do so?
#Html.DropDownList("cities", ViewBag.cities as SelectList, new { onselect = "getLoca();"});
<script type="text/javascript">
function getLoca() {
alert("yes");
$.post('#Url.Action("getLocations","Home")', { 'id': $("#cities").val() },
function (data) {
$("#loca").html(data).show();
});
}
</script>
EDIT:
This is the generated HTML code
<select id="cities" name="cities" onselect="getLoca()"><option value="0">--City-- </option>
<option value="1">City1</option>
<option value="2">City2</option>
<option value="3">City3</option>
<option value="4">City4</option>
<option value="5">City5</option>
</select>;
<select id="loca" name="loca" style="width: 170px" ></select>
Use onchange instead of onselect.
jsFiddle Demo
onselect does not do what you expect - it fires when the user selects text (you know, by dragging the mouse or holding shift and using the arrow buttons), so it is not applicable to a select box, which has no selectable text. It works on certain input elements (like text) and textareas, or you can use it on the window.
onchange fires when the value of a form element changes - so this is what you need.
Note: using inline event handlers in your HTML is not a good idea most of the time. If you can, use addEventListener instead.