Good Afternoon,
Using JSF + Primefaces.
I have a dataTable with inputText field, which performs a listner, and when you end the function or pressing tab, the focus would be to input the low line of the same component.
Googled some things, and it seems that's to be done with JavaScript or jQuery, but I have not much knowledge.
It seems that the clientId of the component has something form: dataTable: 0: input, and the number "0" to manipulate the focus.
Anyone know how to work the focus of components within the dataTable?
Thank you.
You could use the PrimeFaces element <p:focus />, and in the "context" attribute, put the ID of the dataTable. The "context" attribute serves to set the root component to start first input search, so if you are using AJAX, you could update the container where the "dataTable" and the "focus" elements are wrapped, and the first input in the dataTable will recieve the focus after AJAX call:
<p:focus context="dataTable" />
You could use the "for" attribute too, if you want to refer the input directly:
<p:focus for="inputText" />
Take a look to the PrimeFaces documentation: p:focus.
Add proper and dynamic ids for your components then you can identify your elements quite easily.
Consider following code snippet:
<ice:form id="form1"/>
<ice:dataTable id="dataTable1">
...
<ice:inputText id="inputText1" />
<ice:commandButton id="commandButton1" value="Set Focus" onclick="javascript: setFocusOfInput(this);" />
...
</ice:dataTable>
</ice:form>
And the javascript part:
function setFocusOfInput(obj){
var objectId = obj.id;
var requiredIndex = objectId.indexOf(':commandButton1');
var formId = objectId.substring(0, requiredIndex);
alert(formId); /* You will get your form id here, no-matter if you don't set. */
/* Now you can get your required element and do-whatever you want. */
var inputText1 = document.getElementById(formId +':inputText1');
inputText1.focus();
}
Just add a proper id for your element to distinguish it from others.
Related
I have been working all day to try and get the selected values on one set of checkboxes on my Django form and copy the selected ones only to an identical checkbox on my form. If a user clicks on a checkbox in form.author defined below, I want the same identical checkbox to automatically be checked on form.favorite_author defined below.
I've tried a JQuery approach as documented here...Copy Selected Checkbox Value From One Checkbox To Another Immediately Using JQUERY but no luck so far. I've recently begun exploring an avenue with the Modelmultiplechoicefield and the checkboxselectmultiple parameters within the form itself. From what I can tell, when I am using JQuery and trying to check a box on the form, the value is coming back as undefined which is most likely why it is not propagating the checkbox selection to the other checkbox.
Here is my form....
class ManagerUpdateNewAssociateForm(forms.ModelForm):
class Meta:
model = Library
self.fields['author'] = forms.ModelMultipleChoiceField(
widget=forms.CheckboxSelectMultiple(),
queryset=Books.objects.all()
self.fields['favorite_author'] = forms.ModelMultipleChoiceField(
widget=forms.CheckboxSelectMultiple(),
queryset=Books.objects.all()
My HTML...
<div class="spacer83">
{{ form.author }}
</div>
<div class="spacer83">
{{ form.favorite_author }}
</div>
When I tried to trace JQuery, it told me the checkbox selections are undefined. I did read a bit about how Modelmultiplechoicefield, since it uses a queryset it doesn't show the selections, but I can't figure out how to get it to.
Thanks in advance for any thoughts.
In combination with the other issue included in this one, I went back to the JQuery route and explored further. From what I can tell, I was not able to use the class for the input because of the way the HTML for Django forms is generated in this use case. I ultimately was able to leverage the input name and then used the code below to interrogate the checkboxes accordingly:
$(document).ready(function() {
$("[name=author]").change(function() {
let selectedValA = $(this).val();
let isAChecked = $(this).prop("checked");
$(`[name=favorite_author][value="${selectedValA}"]`).prop("checked", isAChecked);
});
});
});
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.
I'm trying to use jQuery geocomplete along with Vue.js to populate a form with geo data.
My code contains this form:
<form>
<label for="get-offer-location">location: </label><input id="get-offer-location" v-model="newoffer.location" type="text"/>
<div style="visibility:hidden">
<input name="lat" type="text" value=""/>
<input name="lng" type="text" value=""/>
</div>
</form>
After I click on a suggested location from the get-offer-location input, it looks like the field is filled out -- but then when I start typing in another field, the location input field reverts to just the letters I typed in for the location search. Try it out here by clicking "post", then "news" or "offers":
https://jsfiddle.net/dvdgdnjsph/157w6tk8/
Can anyone tell me what's wrong?
The problem you are having is that v-model binds on input, since the geolocation dropdown is a plugin that changes the value programatically the input event is not fired, so v-model is not updated. As a case, try typing a space after selecting a location, you will see that it sticks.
Fortunately, v-model is nothing more than syntactic sugar for v-on:input, so you can use v-on to fire your event instead. Considering that you are going to need to unfocus to get out of the box, the blur event is likely to be your best option, so you can simply do:
v-on:blur="newarticle.location = $event.target.value"
Unfortunately, JSFiddle won't let me save or update your Fiddle, but I did get it working with the code above.
For completeness, in case you want to use this behavior extensively, and because the Vue docs are fairly limited in this regard, you may write a custom directive to encapsulate the code:
Vue.directive('model-blur', {
bind: function(el, binding, vnode) {
el.addEventListener('blur', function() {
vnode.context[binding.expression] = el.value;
});
}
});
Then you can use like so:
<input v-model-blur="myVar" />
Here's the JSFiddle: https://jsfiddle.net/4vp6Lvmc/
Can't tell for sure. But it looks like jQuery plugin just changes input#get-article-location value, but not the Vue model. So when you trigger model update (e.g. editing headline) it overwrites complete location with whatever you typed in.
I have something like this for catch the geocomplete event and try to set the vueJS value :
$("#get-article-location")
.geocomplete({details: ".details"})
.bind("geocode:result", function (event, result) {
vm.newoffer.location = result.formatted_address;
console.log('done');
});
But something still appears wrong, I think you should really change the name of your vueJS instance (var vm) it may be use by another script and make troubles.
This is because v-model, as two-way binding, on the receiving-user-input way, listens to the input event on the input element, while js plugins (like jquery-geocomplete) obviously set input values via js, which leads to the view model's data not changing as we discussed in other answers.
To fix this, just listen to the geocode:result event of the plugin and manually change the data with code (there seems to be something wrong with jsfiddle so I'm posting it here):
var vueVM = this;
$("#get-offer-location").geocomplete({ details: ".details" });
$("#get-article-location")
.geocomplete({ details: ".details" })
/***** highlight start *****/
.bind("geocode:result", function(event, result){
console.log(result);
//tried result.something but couldn't find the the same thing as `this.value`
vueVM.newarticle.location = this.value;
});
/***** highlight end *****/
extra knowledge: the mechanism of v-model stated above is usually used in making reusable components, by receiving a value prop from the parent, and emitting an input event with the user-input value when detecting change on the input element in the component. And then we can use <my-component v-model='parentData'></my-component> as the child behaves exactly like a simple input element from the parent's perspective. example
I have a html table containing data rows. I am building add/edit/delete functionality to the table using AJAX.
The format of my table row is as follows:
<tr id="281"><td class="todo-task">fdgdg</td><td>some more data</td><td>EDIT BUTTON</td></tr>
At the moment I have a working AJAX function to both add a new row and edit a row via a prepend().
In order to edit a table row, you click the edit button which pulls the values into the form and submits ... simples so far. Here's the code for the edit click and the form markup. Note the id from the edit click goes into a hidden field in the form.
$("button.edit-todo").bind("click", function(){
var task = $(this).closest('tr').children('td.todo-task').text();
var todoID = $(this).closest('tr').attr("id");
$("div#todo-form input.todo-task").val(task);
$("div#todo-form input.key").val(todoID);
});
...
<form id="mgnt-edit-todo-form" class="record-edit-form">
<input type="text" class="todo-task input" name="task">
<input class="key" name="key" type="hidden" value="279">
<button class="update uk-button uk-modal-close" type="submit">Save</button>
</form>
... and the ajax bit which binds the hidden field for the update.
$("button.update").bind("click", function(e){
var key = $(this).closest('.key').attr('value');
$.ajax({
type: "POST",
url: "update-record.php",
//etc etc etc
The problem
The first update works fine, it will prepend a table row including the id. The issue occurs when I then wish to make a further update to that same "prepended" row. Whilst the DOM shows the markup as correct the function on button.edit-todo will no longer get the id. When looking at the form markup in the DOM, the value of the hidden field is blank.
I've looked at the source in Chrome and I can see that it does not match the view in the browser/DOM. For example, the markup is all the same, but the rows have been put into a different order - it looks as though by date. (There is a date field but I have cut down the fields for this example..) I think this is causing the issue ... question is why? and how do i fix it?
Thanks
Update
Here is my markup in the DOM, looks fine to me.
To be absolutely clear the issue is occuring when clicking the edit button.
It calls the following function (now using 'on':
$("button.edit-todo").on("click", function(){
//load the data from this row
var task = $(this).closest('tr').children('td.todo-task').text();
var client = $(this).closest('tr').children('td.todo-client').text();
var due = $(this).closest('tr').children('td.todo-due').text();
var todoid = $(this).closest('tr').attr('id');
$("div#todo-form input.todo-task").val(task);
$("div#todo-form select").val(client);
$("div#todo-form input.todo-due").val(due);
$("div#todo-form input.key").val(todoid);
});
Clicking row 286 works as intended (it was present on the page load) in that the tr id is added to the hidden field in the form. Clicking row 297 (as far as I'm aware in the DOM?) does not pass the id to the hidden field...
Please help!!! Doing my head in...!
Instead of .bind use .on:
$("button.edit-todo").on("click", function(){
(...)
and
$("button.update").on("click", function(e){
(...)
Using ID for loaded data is not very comfortable way anymore. Use class instead of ID.
Also jQuery has changed "bind" to "on" method. I recommend to use "on".
For example:
$(document).on("click", ".edit-todo", function(){
var task = $(this).closest('tr').children('.todo-task').text();
var todoID = $(this).closest('tr').attr("id");
$(".todo-form .todo-task").val(task);
$(".todo-form .key").val(todoID);
});
Also, source shows the code when the document loads, not the dynamic DOM.
I using an HTML / Javascript combination to add fields dynamically.
Here is the jsfiddle for it: http://jsfiddle.net/kM9Yg/2/
My problem is, if I input values in a field, and then click on the Add More button, a new field gets added but the previous fields' values get reset.
The button to add more is of type <input type="button"/> and not <input type="reset" />
Any way to prevent this?
Use DOM methods, not innerHTML. DOM methods are standardised, innerHTML is not. Some browsers will reflect the current value as the default value, others will not.
You can do:
var el, oEl = document.getElementById('divToClone');
if (oEl) {
el = oEl.cloneNode(true);
// code here to fix duplicate ids and
// set style.display = '' so it's visible
oEl.parentNode.appendChild(el);
}