You need to sign in to do that
Don't have an account?

Javascript / apex / reRender problems
Hi guys.
Bit of a conundrum here...
I've got a VF page that has an inputText field that users use to scan in barcodes using a handheld barcode scanner.
The barcode scanner merely act like a keyboard: it translates the scan to keys, then types those keys and hits enter.
What I'd like to do, is have users scan a barcode, then conduct an apex query. If the results are good, it updates a record, if the results are bad - it throws a pageMessage.
I got some JS that checks when the enter key is hit, and then I envoke the apex. However, there seems to be an issue with the sequence of reRendering and apex, and JS.
When I do the scan into the input field - the page does a refresh - but the apex:PageMessage that should display does not...
Here's what I have so far:
<apex:page standardController="terminalPrepOrder__c" extensions="terminalPrepOrderController" >
<apex:variable var="prp" value="{!terminalPrepOrder__c}"/>
function checkEnter(e){ <!-- e is event object passed from function invocation -->
var characterCode <!--literal character code will be stored in this variable -->
if(e && e.which){ <!--if which property of event object is supported (NN4) -->
e = e
characterCode = e.which <!-- character code is contained in NN4's which property -->
}
else{
e = event
characterCode = e.keyCode <!-- character code is contained in IE's keyCode property -->
}
if(characterCode == 13){ <!-- if generated character code is equal to ascii 13 (if enter key) -->
alert("clicked enter");
otherFindTerminal(); <!-- submit the form -->
return false;
}
else{
return true
}
}
</script>
<apex:pageMessages id="msgs"/>
<apex:form id="theForm"> <apex:actionFunction name="findTerminal" action="{!otherFindTerminal}" reRender="msgs"/> <apex:outputText value="Scan Terminal Barcode "/> <apex:inputText value="{!searchBarcode}" onkeypress="checkEnter(event)"/> <apex:commandButton value="Find" action="{!otherFindTerminal}" id="hitMe" reRender="msgs"/> </apex:form>
Controller:
public PageReference otherFindTerminal() { try { if (searchBarcode != '') { terminal__c enteredTrm = [select Id from Terminal__c T where T.barcodeNumber__c = :searchBarcode limit 1]; terminalPrepOrder__c trmPrp = (terminalPrepOrder__c) controller.getRecord(); trmPrp.Terminal__c = enteredTrm.Id; update trmPrp; } else if (searchBarcode == '' ) { ApexPages.Message invalidSearch = new ApexPages.Message(ApexPages.Severity.ERROR, 'Invalid barcode.'); ApexPages.addMessage(invalidSearch); } } catch (exception e) { ApexPages.Message noTrm = new ApexPages.Message(ApexPages.Severity.ERROR, searchBarcode + ' not found. Please enter the Terminal barcode.'); ApexPages.addMessage(noTrm); } return null; }
So when I click the commandButton - it functions perfectly - It does the query, and rerenders the messages...
When I use the input field and hit enter... it refreshes the page but does nothing...
Please help!
Thanks
This is the example I have executed on basis of Your code and it works. Check this and tell me
Here is the link to screenshot
All Answers
otherfindTerminal() is not defined in javascript to do what you want you need to define an apex:actionFunction this component allows you to call a method on your controller by javascript code. in your case it should be like this
<apex:actionFunction action="{!otherFindTerminal}" name="otherFindTerminal"/>
action is the method to call in the controller, and name is the name the function will have on javascript, it doesnt have to have the same name you can choose any you want for the javascript function.
Include that code in your page. You already have the javascript code that calls the function.
If you have any doubt let me know.
Ignacio.
Thanks Ignacio,
I've changed it to the following:
But still, it just refreshes the page without any messages rendered...
I even did a test of changing the method to display a message no matter what:
And still... nothing...
I'm missing something here.
Two thing:
1) Comments in JavaScript should be like this
// this is a comment
or like this
/* this is another comment */
Using <!-- HTML comment syntax --> will cause an error.
2) Try using Firefix with the Firebug extensions to help identify other errors in your javascript.
Thanks Stephan,
I don't think that's a correct statement - building in visualforce takes care of comment syntax. I've used this comment syntax on many other functioning pages.
I've installed firebug but there are no errors...
The method is called correctly already. That much I know because it does the "return null;" refresh that occurs when the pageReference method is called. The only issue is that it doesn't render any messages...
Put a return false; at the end of the checkEnter JS function. Try putting the PageMessages tag into a outPutPanel and rerender the outputPanel.
Nice one, Srinivas! That was the exact solution for a similar problem I was having. Thanks.
Cheers,
-Philip
No dice guys...
I've modified it as such:
The page "spins" and refreshes or something... so no message appears
If I call the command directly by clicking the commandLink - it works perfectly...
Is there a way to use the checkEnter(e) function to simulate a click on the command link, thus calling the method in a manner that visualforce understands?
Action function doesn't work...
Maybe I can do this whole thing in AJAX without touching apex?
I don't know much about JS... I try and stay away from it, but the fact that I have an input device that's hitting enter really means I have to use JS to check for enter THEN call apex...
its simple
replace inputText with this. return is the culprit :)
Hmm that didn't seem to work either Srinivas...
But... good news... I have gotten some results... not the results I need... but results none-the-less...
Here's what I have now:
PAGE:
CONTROLLER
Now, heres the problem:
If I simply start typing in the input box, the function runs, and calls apex regardless of whether or not I press enter... it simply runs on every key press. I know this, because it does rerender the pageMessages and I see them return errors.
Now... the other issue is, that I tested simply clicking enter in the input box and nothing happens... the page just refereshes! That's the issue:
When a user pushes enter in an input box, it does... something... refreshes the page... tries to submit a form... I dunno...
What's going on here?!
This is the example I have executed on basis of Your code and it works. Check this and tell me
Here is the link to screenshot
Yup... That did it... I don't know what was wrong with mine... I overwrote it all with yours and it works perfectly.
Thank you so much for your help!!!
Thats good to hear.. anytime.. If I can offer any help, I would be happy to do so...
Now I've got another problem... my reRender doesn't seem to work... It only reRenders the Terminal field...
ctrlr
all the additional fields on terminalPb do not update (originLocation, housing id etc....)
Why's that?
Need urgent help with this.
Onchange event on inputtext does;nt seem to work.
<apex:inputtext id="apexText" value="{!apextext}" onchange="test()" / >
where test() is a java script function.
Actually i am using javascript function to populate this field.
My requirement is, whenever this inputtext field value changes, the pageblock table shud be rerendered based on the populated value.
For this, i tried
Action function , Action status also.
But nnothing works.
but for the same inputtext field , instead of populating it using javascript, i tried typing in and then this onchange event works.
I need to find a way to rerender the pageblock table when ever this inputtext field value changes.
Any help is greatly appreciated.
Here is the code
$(document).ready(function() {
$('#datepicker').datepicker({
onSelect: function(dateText, inst) {
var theDate = new Date(Date.parse($("#datepicker").datepicker('getDate')));
//theDate= theDate.format('yyyy-mm-dd');
//$("#getSetSinglePicker").val(theDate);
document.getElementById("{!$Component.apextext}").value=theDate;
}
});
});
<apex:inputtext id="apexText" value="{!apextext}" onchange="test()" / >
Just a thought... can you make an actionFunction that has no action, just a rerender:
<apex:actionFunction name="myRerenderFunction" rerender="panel" />
<apex:inputtext id="apexText" value="{!apextext}" onchange="test()" / > <-- Redundant?
You can also try rerendering the table itself too... I find I have to play around with what I actually rerender alot of the time...
You know what.. just noticed that the field is being populated by JS.
AFAIK, the onChange will NOT work if the CHANGE is performed by JS...
You may have to call the "myRerenderFunction" from the same JS script that is updating the field... that's the problem!
Thanks a lot for the reply!!
Yeah just got it solved using apexfunction
and yes, the main problem was the onchange event was not working on the input text field...
Came across lot of issues and finally got it!!!
All,
Controller method does not get invoked....Can you help me with this??
VF page
function populateList(){
refreshSelectedCountries();
}
<apex:pageBlockSectionItem dataStyleClass="dependentFieldBlockCountry" id="p2">
<apex:outputLabel value="{!$ObjectType.Contact.fields.Countries_Discussed__c.Label}" for=""/>
<apex:outputPanel >
<apex:inputHidden id="textv1" value="{!selectedvalues1}"/>
<apex:actionFunction name="refreshSelectedCountries" action="{!refreshSelectedCountries}" reRender="selectedCountries"/>
<apex:actionRegion >
<!-- Modified for Request 3204 -->
<apex:selectList id="countriesDiscussed" multiselect="true" size="7" styleClass="dependentOptionsCountry" value="{!movedCountries}" >
<apex:selectOptions value="{!countrySelectOptions}">
</apex:selectOptions>
</apex:selectList>
<!-- Modified for Request 3204 -- End -->
<apex:outputPanel style="display: inline-block; vertical-align: top;">
<a href="#" class="moveRightButton" onclick="return populateList()">Move right</a>
<br/>
<br/>
<a href="#" class="moveLeftButton">Move left</a>
</apex:outputPanel>
<apex:outputPanel id="selectedCountries">
<select multiple="multiple" size="7" class="dependentSelectedCountry" id="para3" >
<apex:repeat value="{!selectedCountryOptions}" var="opt1" id="para1">
<option value="{!opt1.value}" id="para2"> {!opt1.value} </option>
</apex:repeat>
</select>
</apex:outputPanel>
</apex:actionRegion>
</apex:outputPanel>
</apex:pageBlockSectionItem>
Controller Method
public PageReference refreshSelectedCountries(){
populateCountry();
return null;
}