Button disable in Visual force page - salesforce

On Standard Object (account) i have a button called SAD. The button is added over there by Visual force page.
Now my question is on Account page, for particular field Picklist value (Eg.. Company type=''Z001') how to disable the SAD button visibility to the all users?

Seems like you are using apex:detail tag in order to show the record detail on visualforce page.
To hide any button you can make use of the below code snippet along with conditions when to hide or when not to.
<apex:page standardController="Account" >
<apex:detail />
<apex:includeScript value="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" />
<script>
$(document).ready(function() {
if({!Account.Company_Type__c == 'Z001'}){
$('[name="REPLACE_BUTTON_NAME_HERE"]').hide();
}
});
</script>
</apex:page>
get your button name by inspecting the button on visualforce page and replace same in the code in place of REPLACE_BUTTON_NAME_HERE

Why not do it with a LWC instead?
You can use the #wire decorator with the getRecord method of the uiRecordApi to grab data from the object based on the id of the current record.
JS file would look something like this:
#wire(getRecord, { recordId: '$recordId', fields:['Company_Type__c'] })
Account;
visible = false;
if (Account.Company_Type__c == 'Z001'){
visible = true;
}
handleClick(){
// use #wire to access Controller class you used for your vf page.
}
You'd place the button in the LWC template. Just use the tag.
HTML File would look something like this:
<template>
<template if:true={visible}>
<lightning-button
variant="normal"
label="SAD"
title="SAD Button"
onclick={handleClick}>
</lightning-button>
</template>
</template>

i found out the solution for this code by adding property in Controller and getting it from controller to VF page.
Here is the code.
Code in Extn class
Public Account AccName{get;set;}
Public Account Acnt{get;set;}
Public user userid;
public boolean stagesDisabled {
get {
userid =[SELECT Id, Country FROM User where Id =:UserInfo.getUserId()];
Acnt = [Select id, Company_Type__c from account where id =: Acc.id];
return( Acnt.Company_Type__c =='Z008' && userid.Country =='XYZ' );
}
}
Code in VF page
<apex:commandButton action="{!SAD}" value="New Sales Area Data" disabled="{!stagesDisabled}" />

Related

VisualForce prevent double clicking on a button

I have done a lot of research on this, and can not figure out the best way to solve this. I am trying to prevent a user from clicking multiple times on a custom button in a VF page. When that is done, they invoke the method related to the button multiple times. I saw quite a few posts with different solutions, but most of them are on posts from 5-10 years ago.
<script src="//ajax.googleapis.com/ajax/libs/jquery/latest/jquery.js"></script>
<script>
function buttonsEnabled(enabled) {
// retrieve all of the buttons or links on the page
// with the css class of btn
var $buttons = jQuery('.btn');
if (enabled === false) {
// add the btnDisabled class to give it the look of being disabled
// add the disabled attribute to actually disable interactability
$buttons.toggleClass('btnDisabled', true).attr('disabled', 'disabled');
} else {
// remove the css class and the disabled attribute
$buttons.toggleClass('btnDisabled', false).attr('disabled', null);
}
}
function doSomeWork() {
// first, call the action function to post the form
doSomeWorkActionFunction();
// second, disable the buttons
buttonsEnabled(false);
// third, return false to prevent the click from
// posting the form a second time
return false;
}
</script>
<apex:form>
<apex:actionFunction name="doSomeWorkActionFunction"
action="{!yourControllerMethod}"
oncomplete="buttonsEnabled(true);"
rerender="whateverYouNeedToRerender"></apex:actionFunction>
<apex:commandLink action="{!yourControllerMethod}"
value="Your Text Here"
id="theCommandLink"
onclick="return doSomeWork();" />
</apex:form>

Why does my <a> taghelper route go dead after its route is used by a form post?

This is a ASP.Net Core MVC project.
In my layout file I have the following Menu link:
<li><a asp-controller="Employees" asp-action="Index">Employees</a></li>
The MVC controller it routes to looks like this:
public IActionResult Index()
{
return View();
}
When I click the link the Action is hit and the view is rendered with my Employee List View.
The Employee List View is bound to an Angular Controller which calls a corresponding Employees Web API GET and the view shows my employee list unfiltered.
Great.
Now we need an Employee quick search from a quick search panel.
So I modify my MVC Employees controller like this:
public IActionResult Index(EmployeeListPageViewModel empListPageVM)
{
return View(empListPageVM);
}
It takes in this Model:
public class EmployeeListPageViewModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
My Quick Search Form looks like this back in the layout file:
<form asp-controller="Employees" asp-action="Index">
<th>Employee Search:</th>
<td><input id="firstName" name="firstName" type="text" placeholder="FirstName" /></td>
<td><input id="lastName" name="lastName" type="text" placeholder="LastName" /></td>
<td>
<button class="btn btn-xs btn-primary glyphicon glyphicon-search">
</button>
</td>
</form>
Now the model is built from the form and sent to my MVC Employees Index action.
And of course I roll all the needed changes through.
Make my Employees Web API controller take in optional params.
FirstName = null, LastName = null.
The employee list view takes in the ViewModel:
#model EmployeeListPageViewModel
Binds to the Angular Controller:
ng-controller="employeesController
Calls getEmployees:
ng-init="getEmployees('#Model.FirstName', '#Model.LastName')
The Angular controller works out whether everything is null or filtering is needed:
/***** List Employees *****/
$scope.getEmployees = function (pfirstName, pLastName) {
var config = {
params: {
firstName: pfirstName,
lastName: pLastName
}
}
$http.get(employeeUrl, config)
.then(function (response) {
// Test front end exception message;
// throw "test exception";
$scope.data.employees = response.data;
})
.catch(function (error) {
$scope.data.employeeListError = error;
});
}
Hope all of this makes sense. Just laying the foundation here.
Now my problem:
Everything seems to work individually.
But, when I go in fresh and click the Employees Menu Link I get my full list.
And when I fill in FirstName And/or LastName in the quick search it works.
But now the Employees menu link is dead. It doesn't fire. It doesn't hit the Employees Index Controller action.
What is it about the form that is killing the Menu Link?
Update 1: After thinking about this I believe the anchor tag helper is looking at the controller and index and saying, "I am already there." So it is not going to the controller action. How do I force it to go even if it is already there?
Update 2: I tried changing the link to this:
<li>Employees</li>
The link works but it is still killed after the form post.
Apparently, no matter how you direct to the link, taghelper, ng-href, straight link, whatever, if you are already there the link will not go.
I had to replace the anchor link in the menu with this:
<li>
<form asp-controller="Employees" asp-action="Index">
<button type="submit" class="navbarLinks">
Employees
</button>
</form>

Click on new button redirect to vf page based on the profile

I have a requirement in which if i click on new button of a custom object, it should get redirected to a VF page if this is a support profile. else it should show the standard page. can someone help me with this.
Below is the code i have tried.
<apex:page standardController="customobject__c" extensions="customvfpagecontroller1" action="{!redirect}">
public PageReference redirect() {
PageReference newPage;
Id tProfile = [select Id from Profile where Name = 'TSupport' limit 1][0].Id;
Id profileId=userinfo.getProfileId();
if(profileId == tProfile)
{
newPage = Page.vfpage1;
return newPage.setRedirect(true);
} else {
//it should redirect to standard new page of the custom object
}
On the Custom Object page, at the very top click "Buttons, Links, and Actions" > New Button or Link.
Label it New, and Name it New_Custom or something.
Then your logic can be along the lines of
IF({!$Profile.Name}=='TSupport','/apex/vfpage1',URLFOR($Action.CustomObject__c.New, null, save=1))
You'll unfortunately have to statically set the /apex/vfpage1 since $Page is not supported there.

Unable to bind Component attribute with controller

I am trying to develop a visualforce custom component which takes an attribute from a visual force page. I need to access that attribute in controller's Constructor so that i can brings some records from database and i need to display those records in the Component. But problem is that i am not getting Attribute value in Controller.
See the below code to understand the problem clearly..
Controller :
public with sharing class AdditionalQuestionController {
public String CRFType {get;set;}
public AdditionalQuestionController () {
system.debug('CRFType : '+CRFType);
List<AdditoinalQuestion__c> lstAddQues = [Select AddQues__c from AdditoinalQuestion__c wehre CRFType = :CRFType];
system.debug('lstAddQue : '+lstAddQue);
}
}
Component :
<apex:component controller="AdditionalQuestionController" allowDML="true">
<apex:attribute name="CRFType" description="This is CRF Type." type="String" required="true" assignTo="{!CRFType}" />
<apex:repeat value="{!lstAddQue}" var="que">
{!que}<br />
</apex:repeat>
</apex:component>
VisualForce page :
<apex:page >
<c:AdditionalQuestionComponent CRFType="STE" />
</apex:page>
Thanks,
Vivek
I believe the issue here is that you're expecting the member variable to have a value inside the constructor — the snag is that the instance of the class is being constructed! It doesn't exist yet and so there is no way that a non-static member variable could be given a value prior.
Instead of doing the query in your constructor, specify your own getter for lstAddQue and do the query in there when you need the data. Of course, you may want to cache the value so that the query is not run every time, but from the looks of things that won't be relevant here.
Setter methods on the attributes in a VF component appear to be called after the constructor has returned, unfortunately. Here's an alternative solution for your controller that uses a getter method to populate your list (which would be called after your CRFType member variable has been set):
public with sharing class AdditionalQuestionController {
public String CRFType {set;}
public AdditionalQuestionController () {
system.debug('CRFType : '+CRFType); // this will be null in the constructor
}
public List<AdditoinalQuestion__c> getLstAddQue() {
system.debug('CRFType : '+CRFType); // this will now be set
List<AdditoinalQuestion__c> lstAddQues = [Select AddQues__c from AdditoinalQuestion__c wehre CRFType = :CRFType];
system.debug('lstAddQue : '+lstAddQue);
return lstAddQue;
}
}

How to implement "Cancel" functionality in a VisualForce Page

I know that this is how to save a record
<apex:commandButton action="{!save}" value="Save"/>
I want a button to NOT save the current record (ie. Cancel) and navigate to the list of saved record (ie. list of objects for that object type).
Something like this...
<apex:commandButton action="{!cancel}" value="Cancel"/>
The list view for an object is your base URL / the 3 letter prefix for your object / o, for example:
https://na1.salesforce.com/a0C/o
So you could just create an action method that returns a Pagereference with the appropriate URL and set to redirect (pr.setRedirect(true)).
Alternatively, you could use your controller as an extension to a standard controller, and just call cancel on the standard controller:
// controller extension
public class TimeSheetExtension
{
ApexPages.standardController m_sc = null;
public TimeSheetExtension(ApexPages.standardController sc)
{
m_sc = sc;
}
public PageReference doCancel()
{
return m_sc.cancel();
}
}
// page
<apex:commandButton action="{!doCancel}" value="Cancel"/>
Note that this doesn't necessarily take you to the list view, it'll return you to the last page you were viewing before going to the VF page.
You should also add the immediate tag to your Cancel button, so that the form doesn't run any validation before performing the Cancel operation.
<apex:commandButton action="{!cancel}" immediate="true" value="Cancel"/>
See http://blogs.developerforce.com/developer-relations/2008/12/using-the-immediate-attribute-on-commandlinks-and-commandbuttons.html
While applying cancel operation visualforce you should stop the form validation.Use below any one methods to stop the form validation based on your requirements.
Method 1:
Using
html-5 in doctype in visualforce page
means you should use html-formnovalidate and immediate in cancel button. For example
<apex:commandButton action="{!cancel}" value="Cancel" immediate="true"
html-formnovalidate="formnovalidate" />
Method 2:
you should use immediate key word only need for stopping form validation. For Example
<apex:commandButton action="{!cancel}" value="Cancel" immediate="true"/>
One of the other answers suggested calling the standard controller's cancel action so I want to expand on that since it led me in the direction to solve my similar problem.
If you want to cancel an edit as an ajax request without refreshing the whole page, declare the action as void and don't return the page reference, but still call the 'cancel' action on the standard controll. Make sure the command button specifies the rerender attribute.
// controller extension
public class TimeSheetExtension
{
ApexPages.standardController m_sc = null;
public TimeSheetExtension(ApexPages.standardController sc)
{
m_sc = sc;
}
public void doCancel()
{
m_sc.cancel();
}
}
// page
<apex:commandButton action="{!doCancel}" value="Cancel" rerender="container_id"/>

Resources