Apex getter returning wrong value - javascript

I have javascript function in my salesforce page to validate if one of the contacts have open cases. This function calls an apex getter to get the value. The problem I`m facing is that the apex getter is always returning the wrong boolean. I tried debugging it, everything seems to work but for some reason the returned bool is wrong.
apex function:
public Boolean openCase{
get{
if (Contacts.size() > 0){
for(cContact wContact: dicContacts.values()){
if(wContact.selected){
if(wContact.con.account.Number_of_open_Financial_Review_Cases__c > 1){
return true;
}
}
}
return false;
}
set{}
}
js function:
function validateOpenCases(sendEmail){
doIt = true;
oc = {!openCase}; // <<== problem here
alert(oc);
if (oc)
{
doIt=confirm('blabla?');
}
if(doIt){
// do stuff
}
else{
// do nothing
}
}

You should not bind Apex objects/variables directly in JavaScript (like you have {!openCase};). I've had many issues with this before. Instead use JavaScript Remoting or the Ajax Toolkit.
Update
Another option is to use a hidden Visualforce input to store your bound Visualforce value. Then you can get that value in your JavaScript.
Here's an example:
<apex:page controller="myController">
<script>
function getInputEndingWith(endsWith)
{
// put together a new Regular Expression to match the
// end of the ID because Salesforce prepends parent IDs to
// all elements with IDs
var r = new RegExp("(.*)"+endsWith+"$");
// get all of the input elements
var inputs = document.getElementsByTagName('input');
// initialize a target
var target;
// for all of the inputs
for (var i = 0; i < inputs.length; ++i)
{
// if the ID of the input matches the
// Regular Expression (ends with)
if (r.test(inputs[i].id))
{
// set the target
target = inputs[i];
// break out of the loop because target
// was found
break;
}
}
// return the target element
return target;
}
function validateOpenCases(sendEmail)
{
doIt = true;
oc = getInputEndingWith("OpenCase").value;
alert(oc);
if (oc === "true") {
doIt = confirm('Are you sure?');
}
if (doIt) {
// do stuff
}
else {
// do nothing
}
}
</script>
<apex:form>
<apex:outputpanel>
<apex:inputhidden id="OpenCase" value="{!openCase}" />
</apex:outputpanel>
<input type="button" class="btn" onclick="validateOpenCases('Send');" value="Validate" />
</apex:form>
</apex:page>

Related

How to make other JQuery run when a separate function runs?

I have the JS code below which filters based on checkboxes being checked or not (I don't think you need to see all the HTML because my question is rather simple/general, I think). All this code works fine, but I added a new function at the bottom (I noted it in the code) that simply has an uncheck all button for one of the sets of checkboxes (because there are like 30 checkboxes and I don't want the user to have to uncheck them all manually).
Anyway, the new script works properly too, except that the overall unrelated script that compares all checkboxes needs to run each time the new Uncheck All/Check All button is clicked.
Is there a simple way to make sure all the other JS runs when this new script is run?
I could be wrong, but I think I just need to somehow trigger this function inside the NEW FUNCTION:
$checkboxes.on('change', function() {
but am not sure how to do that.
ALL JS:
<script>
$(window).load(function(){
Array.prototype.indexOfAny = function(array) {
return this.findIndex(function(v) {
return array.indexOf(v) != -1;
});
}
Array.prototype.containsAny = function(array) {
return this.indexOfAny(array) != -1;
}
function getAllChecked() {
// build a multidimensional array of checked values, organized by type
var values = [];
var $checked = $checkboxes.filter(':checked');
$checked.each(function() {
var $check = $(this);
var type = $check.data('type');
var value = $check.data('value');
if (typeof values[type] !== "object") {
values[type] = [];
}
values[type].push(value);
});
return values;
}
function evaluateReseller($reseller, checkedValues) {
// Evaluate a selected reseller against checked values.
// Determine whether at least one of the reseller's attributes for
// each type is found in the checked values.
var data = $reseller.data();
var found = false;
$.each(data, function(prop, values) {
values = values.split(',').map(function(value) {
return value.trim();
});
found = prop in checkedValues && values.containsAny(checkedValues[prop]);
if (!found) {
return false;
}
});
return found;
}
var $checkboxes = $('[type="checkbox"]');
var $resellers = $('.Row');
$checkboxes.on('change', function() {
// get all checked values.
var checkedValues = getAllChecked();
// compare each resellers attributes to the checked values.
$resellers.each(function(k, reseller) {
var $reseller = $(reseller);
var found = evaluateReseller($reseller, checkedValues);
// if at least one value of each type is checked, show this reseller.
// otherwise, hide it.
if (found) {
$reseller.show();
} else {
$reseller.hide();
}
});
});
//NEW FUNCTION for "UNCHECK ALL" Button
$(function() {
$(document).on('click', '#checkAll', function() {
if ($(this).val() == 'Check All') {
$('input.country').prop('checked', true);
$(this).val('Uncheck All');
} else {
$('input.country').prop('checked', false);
$(this).val('Check All');
}
});
});
});
New button HTML for the new UNCHECK portion:
<input id="checkAll" type="button" value="Uncheck All">
I kept researching and discovered the trigger() function to handle this.
http://api.jquery.com/trigger/

javascript validating the whole form

Friends i am new to javascript, I am trying to write a script to validate the entire form whenever any input field value is changed of input fiels with the data attribute of required.
HTML
<form>
<input type="text" name="FirstName" class="inputField" data-required="true"></input>
<input type="text" name="MiddleName" class="inputField"></input>
<input type="text" name="LastName" class="inputField" data-required="true"></input>
</form>
SCRIPT
var field, required, isValid, fieldVal;
function validatedForm() {
field = document.querySelectorAll('.inputField');
document.getElementById("submitButton").disabled = true;
var isValid = true;
for(var i=0; i < field.length; i++){
required = field[i].dataset.required;
if(required){
field[i].addEventListener('blur', function(e){
fieldVal = this.value;
if(fieldVal == ''){
isValid = false;
}
checkSubmitBtn();
}, true);
}
}
function checkSubmitBtn() {
if(isValid = true) {
console.log(isValid);
document.getElementById("submitButton").disabled = false;
}
}
}
window.addEventListener("load", validatedForm);
PROBLEM 1:
The isValid is not updating hence even an empty blur on the input field makes the button disable to be false.
PROBLEM 2:
In case there are multiple forms on the page then how to validate only the desired forms .. just like in jQuery we add a script tag in the end to initialize the script according to it.
PROBLEM 3:
Is there a way to change the disable state of the button without the GetElementID ... I mean if that can be managed depending on the submit button of that particular form on the page where the script is suppose to work.
Any help will be highly appreciated. Thanks in advance.
I think you need something like the following form validation..
<script type="text/javascript">
var field, fieldVal, required = false;
function validatedForm() {
field = document.querySelectorAll('.inputField');
document.getElementById("submitButton").disabled = true;
field.forEach(function(elem) {
required = elem.dataset.required;
if(required){
elem.addEventListener('blur', function(e) {
checkSubmitBtn(field);
});
}
});
}
function checkSubmitBtn(field) {
var isDisabled = false;
field.forEach(function(elem) {
fieldVal = elem.value.trim();
if(fieldVal == ''){
isDisabled = true;
return false;
}
});
document.getElementById("submitButton").disabled = isDisabled;
}
window.addEventListener("load", validatedForm);
</script>
I hope it helps...
There are quite a few things going on here. First, your checkSubmitBtn function used a single = operator in the if statement. This won't actually check the variable, it instead will set the variable to that value. Here is the fixed function:
function checkSubmitBtn() {
if (isValid == true) {
document.getElementById("submitButton").disabled = false;
}
}
You mentioned not wanting to use getElementById. There are a few ways around this. One way would be to call the function once and store it in a variable to use later, like so:
var button = document.getElementById("submitButton");
...
function checkSubmitBtn() {
button.disabled = !isValid;
}
Another way would be to use jQuery. It still is technically calling getElementById in the backend, but the code is much simpler. If you wanted to avoid that, you also can still combine this with the technique I described above.
$("#submitButton").attr("disabled", !isValid);
I'd also like to point out that your code doesn't account for a situation where a form goes from invalid (starting point) to valid and back to invalid again. Say a user types in all of the fields but then backspaces everything. Your code will fall apart.
Lastly, your <input> HTML tags should not be closed. There are certain tags that are considered "self-closing", i.e. you don't have to write the closing tag, </input>.

ng-disabled with function that trigger when change

I have a submit validation button that need to be enable when all fields is being entered correctly. As the validation is too complex and is not able to be solve by using formName.$invalid alone, i need to write a function to cater the validation. I expect that the shouldEnable function to be trigger for each of the model changes inside. But it does not. Os is there any alternative for this?
Initial
<button ng-disabled="formName.$invalid">Submit</button>
Expected
<button ng-disabled="shouldEnable()">Submit</button>
$scope.shouldEnable = function() {
$scope.isEnable = true;
angular.forEach($scope.form.input2, function(val) {
if($scope.form.input2.inputA && $scope.form.input2.inputB) {
isEnable = false;
}
})
}
Your function needs to return boolean value:
$scope.shouldEnable = function() {
var isEnable = true;
// make necessary checks
return isEnable;
}
If you are using Angular's data-binding, You should use something like this :
<button ng-disabled="shouldEnable">Submit</button>
// yourObject is the object you've map in the form
$scope.$watch('yourObject', function(newObject) {
$scope.shouldEnable = isValid(newObject);
});

AngularJS: Write inside input box via JS, Do not transfer the value in the JSON

Background: I have an external device (barcode reader) that sends information back to a tablet when the user scans something. I subscribe to that channel and I need the value to be inside the currently focused cell and write it there.
Bug: I can catch the subscription and write the value visually in the Input box, but it never reaches the JSON underneath.
I also tried $scope.$apply() but it did not change anything (maybe I used it wrong).
"Working" Plunker with the problem
$scope.randomClickOnStuff = function() {
// Here Randomely publish stuff with value so we can write it in specific field.
window.setTimeout(function() {
if (!$scope.stopMe) {
vm.objectOtSubscribeTo.publish(channelToUse, Date.now());
$scope.randomClickOnStuff();
} else {
// Stop the loop.
}
}, 1000);
};
var callbackCompleted = function(resultValue) {
// Important code Here
// Code to write in the input box here.
console.log(resultValue);
if (document.activeElement.localName == "input") {
// Option 1:
//--> Work Visually <-- but do not put the value inside the JSON.
document.activeElement.value = resultValue;
$scope.$apply();
// Option 2:
// http://stackoverflow.com/questions/11873627/angularjs-ng-model-binding-not-updating-when-changed-with-jquery
// Problem: The "document.activeElement.attributes['ng-model'].value" is not link with the scope, but with the ng-repeat row. So I have access to the Scope, but not the Row item.
//var binding = document.activeElement.attributes['ng-model'].value;
// Rule: I might not know where the Item is so I cannot do $scope.complexObject[row][binding]
} else {
console.log("not inside a Input box.");
}
};
vm.objectOtSubscribeTo.subscribe(channelToUse, callbackCompleted);
Thanks
One solution would be to keep track of the selected row and cell by setting them on focus of one of the cells
$scope.focusedRow = false;
$scope.focusedCell = false;
$scope.setFocused = (row, cell) => {
$scope.focusedRow = row;
$scope.focusedCell = cell;
};
/* In callback... */
if ($scope.focusedRow !== false && $scope.focusedCell !== false) {
$scope.$apply(
() => $scope.complexObject[$scope.focusedRow]
["cellInTheRow"][$scope.focusedCell] = resultValue
);
}
<input type="text" ng-model="row.cellInTheRow[key]"
ng-focus="setFocused(rowKey, key)" ng-blur="setFocused(false, false)">
Example: https://plnkr.co/edit/och5PoepJuRde0oONIjm?p=preview

Javascript size of a form object

I have a very critical issue.
Below is my jsp code:
<html:select property="city" name="city" onchange="javascript:checkCity(this);">
<html:option value="N">NewYork</html:option>
<html:option value="F">France</html:option>
<html:option value="I">Italy</html:option>
<html:option value="P">Paris</html:option>
</html:select>
There can be single or multiple html select since my <html:select> is placed in for loop.
Below is my Javascript code:
var citySelected = new Array();
function checkCity(selObject)
{
var form = document.forms[0];
var cityObj = form["city"];
var len = cityObj.length;
if(selObject==cityObj) // if there is single <html:select> selObject is same as city Object.so this logic works fine
{
if(cityObj.value==cityObj.options[3].value)
{
alert("You have selected Paris City");
citySelected[0] = true;
}
if(!cityObj.options[3].selected && cityObj[0])
{
var result = confirm("You have selected cities other than paris");
if(result)
{
citySelected[0] = false;
}
else
{
cityObj.options[cityObj.options.selectedIndex].selected=false;
cityObj.options[3].selected=true;
}
}
}
else{
for(var i=0; i<len; i++) { //if there are multiple <html:select> then take length of form object n iterate
if (selObject == cityObj[i] )
{
if(cityObj[i].value==cityObj[i].options[3].value) // if 3rd option is selected
{
alert("You have selected Paris City");
citySelected[i] = true;
}
if(!sctypeObj[i].options[3].selected && citySelected[i]) //if 3rd option is deselected
{
var result = confirm("You have selected cities other than paris");
if(result)
{
cityObj[i] = false;
}
else
{
cityObj[i].options[cityObj[i].options.selectedIndex].selected=false;
cityObj[i].options[3].selected=true;
}
}
}
}
}
}
Below is Javascript which works on jsp onload():
function onload()
{
var form = document.forms[0];
var formObj = form["city"];
var size=formObj.size;
var len = formObj.length;
for(var i=0; i<len; i++) {
citySelected[i] = false;
}
if(size==0){ //if there is seingle <html:select> element
var cityvalue=formObj.value;
if(cityvalue=="P")
{
citySelected[0] = true;
}
}
else
{
for(var i=0; i<len; i++) { //if there are multiple <html:select> elements
var cityvalue=formObj[i].value;
if(cityvalue=="P")
{
citySelected[i] = true;
}
}
}
}
Here is where am finding problem. Onload if there is single or multiple <html:select> elements the logic works fine.But when there are no <html:select> elements at all in my jsp per say if I have option to delete all dropdowns then my jsp throws Javascript error:
"size is null or not an object".
How do I resolve this? In onload() function I am differentiating between <html:select> element using size.
if(size==0)
{
//logic for single <html:select>
}
else
{
//logic for multiple html select
}
But when there are no <html:select> elements at all in my jsp per say if I have option to delete all dropdowns then my jsp throws Javascript error:
"size is null or not an object".
How do I resolve this? Any help would be great..
An alternate way to determine the number of <select> elements within a form would be to use jQuery's selectors like so:
$('#myForm select').length // returns number of <select> elements in the form
You can use the fact that null/undefined evaluates to false in Javascript, like so:
if(!size)
{
//logic for single <html:select>
}
else
{
//logic for multiple html select
}
The line var size=formObj.size; could be the cause of the problem. Try using an "or" statement to prevent the error when the size attribute is null or undefined:
var size = formObj.size || 0;
If for single select element length is returning 4, then it seems that other select elements present inside jsp with the same name and those are hidden.
However, getElementByName('propertyName') is not a correct function to iterate collection type, rather we need getElementsByName('propertyName').
Use:
var formObj = document.getElelementsByName('city');
var length = formObj.length;
if(length == 0) {
// No select element
}
if(length == 1) {
// One select element
} else {
// More than one select elements
}
I am not sure how size will help here, this is not required. Size always will be returning undefined in this case.

Categories