jsf.ajax.request not working completely - javascript

I am attempt to make a custom autocomplete box but I am having some trouble. Right now I have an input that calls this function on keydown
function pingAutoComplete(event)
{
console.log("pingAutoComlete Called");
window.clearTimeout(window.keyTimeout);
//Wait 2 seconds before we attempt to pingAutoComplete incase user has not finished typing
window.keyTimeout = setTimeout(function() {
jsf.ajax.request(event, "keydown", {execute:'searchTerm',render:'autoCompletePanel'})
autoCompleteLayoutPanel.show();
return false;
}, 2000);
return false;
}
The auto complete panel contains a bunch of selects that look like this
<h:selectOneListbox id="vehicleResult" title="Vehicles"
value="#{searchBean.searchTerm}"
converter="entityConverter"
required="false"
rendered="#{!searchBean.filterAutoComplete().isEmpty()}">
<f:selectItems value="#{searchBean.filterAutoComplete()}"
var="searchItem" itemValue="#{searchItem}"
itemLabel="#{searchItem.displayString}"
itemLabelEscaped="true" />
</h:selectOneListbox>
Now when the javascript is called it seems to be hitting searchBean.filterAutoComplete() on the back end, but it is not actually updating the select list in the gui. Anyone know why?

You have to specify the exact client ID. That is the value of the id attribute of the generated HTML element, not of the JSF component itself. If the JSF components are placed in a <h:form>, then the client ID will by default be prepended with its ID.
Thus the following panelgroup
<h:form id="form">
<h:panelGroup id="autoCompletePanel">
will have a client ID of form:autoCompletePanel. You need to specify exactly that ID in the render attribute. The same rules also applies to execute by the way.

Related

Uncaught TypeError: document.querySelector(...).click is not a function on automated process

Expected Behaviour: I am adding the value from a select element to a 3rd party API input element using the select element's onchange event. Once the text value has been added to the input element, the search button must be clicked to fully automate the process.
Returned Behaviour: Although the text value can be seen in the input, once it gets focus, it clears the text. When the text is visible and the search button is clicked, nothing happens. When I add the text value manually to the input and then click search it works fine. Not too sure what to do to make sure the text remains in the input.
Code for my select and the input as follow -
function vehicle_vin() {
var use_vehicle_vin = document.getElementById('get_vehicle_make');
use_vehicle_vin = use_vehicle_vin.options[use_vehicle_vin.selectedIndex].value;
var add_vehicle_vin = document.getElementById('id-vin-frame-search');
add_vehicle_vin.value = use_vehicle_vin;
alert(add_vehicle_vin.value);
//This works fine, but please see my notes above, when I put focus on the input, my value dissapears...
//I have tried, as per various search results the following QuerySelector, no luck in the search button being clicked.
//document.querySelector('.CLOYw6ixbVCoWy9pu904a ._2DcnCzqTJKrTWusHYHyHEf').click();
//I then changed to the svg element, the same error was returned...
var x_vin = document.querySelector('._15YY4Hl-2b6wr1smId9ZlA').click();
//I also tried to do a setTimeout, also did not work, then added the below, this returns nothing -.
if (x_vin && x_vin.length) {
alert("All true, click...");
setTimeout(() => { x_vin[0].click(); }, 750);
alert("clicked");
} else {
alert("not clicked");
}
}
<select id="get_vehicle_make" name="get_vehicle_make" title="Select a vehicle from your current car park. This V.I.N. will be added to the Search Input and will automatically load your search." onchange="vehicle_vin();">
<option value="" selected >Select Saved Vehicle</option>
<option value = "123456asdfgh09876" >Kia, Sportage, 2. CRDi</option>
</select>
<!--3rd party Api input and search button-->
<input type="text" id="id-vin-frame-search" name="vin-frame-search" placeholder="VIN or FRAME" class="_2UbmnxPVuhV1aqBHdE1oDO">
<button type="button" class="CLOYw6ixbVCoWy9pu904a _2DcnCzqTJKrTWusHYHyHEf">
<span class="_24-MeE_aY0KDledQMmmJAn">
<svg width="16" class="_15YY4Hl-2b6wr1smId9ZlA">
<use xlink:href="#search"></use>
</svg>
</span>
</button>
As above, I have tried many things with no success and will really appreciate any help available, javascript is not my strong point...
querySelector returns single element, to get multiple elements use
querySelectorAll
As you are trying to access single and first element, then you can use querySelector.
So the x_vin will contain element directly (not nodelist)
So you are trying to click element programmatically (From Javascript), Then you have .click() function
Just wrapped the click function in timeout (e.g., below)
setTimeout(() => {
console.log(document.querySelector('._15YY4Hl-2b6wr1smId9ZlA'));
document.querySelector('._15YY4Hl-2b6wr1smId9ZlA').click();
}, 1000) //1 second delay
Update
Hey I just found that svg does not have click function (I thought
every element does). Solution is to click parent element
programmatically, In your case either click span or button

Autocomplete with restriction

I am trying to do, using bootstrap, an autocomplete function which works over an inputText having to show the options list only when the related inputText contains more than 4 characters.
This is my xhtml:
<script>
$(function(){
jQuery.noConflict();
var autocompPerson = $('.autocomp');
autocompPerson.typeahead({
source: [#{operationsFormBean.allPersonFilteredList}],
});
});
</script>
<div class="col-md-8 pb0 pl0">
<h:inputText id="auPerson"
value="#{backingBeanRef['selectedPersonName']}"
styleClass="form-control autocomp wo-borders bg-transparent">
<a4j:ajax
event="keyup" listener="#{backingBeanRef['personFilteredList']}"
render="operations_form_panel"/>
</h:inputText>
</div>
The method personFilteredList() is in my java Bean and it is the one who controls if the input has or not more than 4 characters.
If I use the event "keyup", whenever I write a character in my inputText, I lose the focus over it and the list disappears immediatly. I know it is working since it shows the list only when I write more than 4 characters. The problem is : when the method is called I have to render the inputText in order to show the list and it makes me lose the focus over which makes the list disappears.
Do you know if I can use a js function like "updater" which updates my selectedPersonName every single time I write something without using the event keyup?
Thanks in advance.
Use the AJAX oncomplete JS callback hook to update your source for typeahead and re-render just the inputText. See this post for resetting the source in bootstrap typeahead.

JS Ajax OnClick: How to execute php code multiple times?

I have an html button with an onclick attribute which runs a jQuery AJAX function pointing to php code.
The php code writes HTML in an output HTML <select> element(the element remains hidden until the javascript runs.)
This is working great to populate the <select> when an "add another" button is clicked.
The problem is it adds one and only one. I want to be able to have a new <select> tag populate with each click of the "add another" button up to a max of 2.
The JS in question:
var genre_dropdown = function genre_dropdown() {
$('.genre_output').css('display', 'block');
$.ajax({
url:'../includes/functions/genre_dropdown.php',
complete: function (response) {
$('.genre_output').html(response.responseText);
},
error: function () {
$('.genre_output').html('Bummer: there was an error!');
}
});
return false;
}
The HTML in question:
<select name="genre_id[]" autocomplete="off" class="genre_output"></select>
<select name="genre_id[]" autocomplete="off" class="genre_output"></select>
<div class="button add-genre-button" onclick="return genre_dropdown();">+ Add Existing Genre</div>
I thought I could include 2 html <select> elements for the php to populate into, the code would execute from one to the next. I see why this is not correct, the code is running in both at the same time. I'm at a place where I'm considering have 2 buttons ("add one", "add another") but that seems redundant and not correct, especially considering I want a scale-able technique (the max may not always be 2.) I need help.
Your php request is fine.
I simply mean define a variable as your using javascript i.e.:
var sel = '<select name="genre_id[]" autocomplete="off" class="genre_output">' + response + "</select>';
and then each time you do a request it will include the response as the value of the element. This would allow you to append the parent div as many times as you want. Finally, use a simple if counter to decide whether to keep appending or not:
if ($(".genre_output").length <= 2){
$("PARENT_DIV_ID").append(sel);
};
Is this clearer? #kaari
Assuming you want to keep previous values in dropdown then you can try append() instead of html()
$('.genre_output').append(response.responseText);

IS Accessing DropList Value of Sitecore WFFM Control in Javascript Possible?

I am using Sitecore 7.2 with Web Forms for Marketers 2.4.
Using wffm form designer I created a form that has a droplist in it.
I want to be able to hide or unhide another field in the same form based on the selected value of the droplist. Through my research I came up with exporting the form (via form designer export) and pointing the sublayout to that exported form.
I then added and onChange event to the droplist.
<cc3:droplist runat="server" title="Country" emptychoice="True" id="field_xyz" cssclass="scfDropListBorder fieldid.%7bxyz%7d name.Country" controlname="Country" fieldid="{xyz}" enableviewstate="False" onchange="checkField()">
I then added a javascript to the bottom of the page.
function checkField() {
alert("Hello! I am an alert box!!");
var a = document.getElementById("field_xyz");
alert(a.options[a.selectedIndex].value);
var cityTextBox = document.getElementById("field_abc").parentNode.parentNode;
if (a == "United States") {
cityTextBox.style.display = "block";
} else {
cityTextBox.style.display = "none";
}
alert("Ending Script");
}
I can get the 'Hello!' alert to show every time but not the 'ending' alert and the value of 'a' is always null from what I can tell.
Is what I'm trying to do even possible in Sitecore?
I read something else that said they had a problem because of encapsulation and protection levels.
I can also confirm that when I submit the form it does show up in the WFFM reports so I know it is submitting properly.
Any help/advice/direction would be appreciated.
I've never used the export functionality so can't comment to it's effectiveness or ease of use. My suggestion would be to simply use from custom css classes and jquery on the front-end to hide/show depending on the selected value.
Create 2 new css classes under /sitecore/system/Modules/Web Forms for Marketers/Settings/Meta data/Css Classes. Call them "hide-dependent" and "dependent-field"
Add your fields and then on the country field select "hide-dependent" as the CSS class, and for the City select "dependent-field"
Add the following Javascript to your own sites js file.
The code will bind a handler to fire onchange, checked the selected value and then hide/show all field with the dependent-field class. Specifying the chained field-border ensures that we are hiding the whole row and not just the select box.
(function ($) {
var HideDependentFied = function (value) {
var condition = (value == "USA");
$(".dependent-field.field-border").toggle(condition);
};
$(document).ready(function() {
var $field = $(".hide-dependent.field-border select");
$field.on("change", function() {
HideDependentFied(this.value)
});
HideDependentFied($field.val());
});
})($scw);
The above code is using an Immediately Invoked Function Expression and passing is $scw, which is the jQuery variable used by WFFM.
You may also want to fire the function on document ready, to ensure the field is hidden on load and only shown when the appropriate value is selected.

"Bubble" validation message on non-form element

I have some elements on a page and I want to make use of the nice bubble style messages such as described here HTML5 form validation. It seems that to use them it is required they are within a form element and they only can be used on validation once the form is attempted to be submitted.
Taking from the linked example, I want to know how to get the following to work as described (i.e for this example pop a bubble message if the user sets a time before now)
Fiddle for this: My attempt without form
<body>
<label>
Arrival Date:
<input id="arrivalDate" type="date" onchange="dateChanged()" />
</label>
<input type="button" value="Test Reservation"></input>
<script type="text/javascript">
function dateChanged(e){
var arrivalDate = document.getElementById("arrivalDate");
var value = new Date(arrivalDate.value);
if (value < new Date()) {
arrivalDate.setCustomValidity("Arrival date must be after now!");
} else {
arrivalDate.setCustomValidity("");
}
arrivalDate.checkValidity();
}
</script>
</body>
Specifically in my case I have 2 KendoUI DateTimePickers being used to select the time range which is used to display information dynamically on the page. I'd like if I could use these bubble messages if the user tries to make the start time after the end time.
There's no way to manually trigger the validation. Using .checkValidity() will only return true/false if the context of what your checking is valid or not, i.e. if you did form.checkValidity() it will check if all form elements are valid, or input.checkValidity() only check the validity of that single element.
The only way to trigger the validation is on submit. You can simulate this by having a submit button and calling the click function.
if (!arrivalDate.checkValidity())
{
document.getElementById('submit_reservation').click();
}
Fiddle: http://jsfiddle.net/QGpQj/3/
Note: I've added window.dateChanged = .... because of your inline event listener. You really should be using .addEventListener or, ideally, jQuery for this to add backwards compatability support for those non-supported browsers.

Categories

Resources