I have visualforce page like this
<apex:selectList label="Food" multiselect="true" value="{!selectedFood}" size="5">
<apex:selectOptions value="{!FoodList}"></apex:selectOptions>
</apex:selectList>
<apex:selectList label="Area" value="{!selectedDetailFood}" multiselect="true" size="5">
<apex:selectOptions value="{!DetailFoodList}"></apex:selectOptions>
</apex:selectList>
and the apex class like this.
public List<selectOption> getFoodList(){
List<selectOption> options = new List<selectOption>();
options.add( new selectOption('', '--select--') );
options.add( new selectOption('Warm Food', 'Warm Food') );
options.add( new selectOption('Cold Food', 'Cold Food') );
return options;
}
public List<selectOption> getDetailFoodList(){
List<selectOption> options = new List<selectOption>();
options.add( new selectOption('', '--select--') );
options.add( new selectOption('Ramen', 'Ramen') );
options.add( new selectOption('Soto', 'Soto') );
options.add( new selectOption('Frozen Mix Salad', 'Frozen Mix Salad') );
return options;
}
Selection 1 have value = warm food, cold food (Static Value *Hardcode not from soql) and the other selection have value based on value that i choose in selection 1, example if i choose warm food in selection 1, the value that will show in selection 2 is ramen and soto.(Static Value *Hardcode not from soql)
is it possible make it in apex and visualforce salesforce? if it so how to make it? thank you
Related
I am working with three models:
User Model
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array<int, string>
*/
protected $table = 'users';
protected $fillable = [
'name',
'email',
'password',
'group'
];
...
public function permission()
{
return $this->hasMany(Permission::class);
}
}
Profile Model
class Profile extends Model
{
use HasFactory;
protected $table = 'profiles';
protected $fillable = [
'profile_name',
'first_name',
'last_name',
'profile_type',
'TFN',
'ABN',
'ACN',
'Address',
'Email',
'Phone',
'established_date',
'Notes',
'activated'
];
...
public function permission()
{
return $this->hasMany(Permission::class);
}
}
Permission Model
class Permission extends Model
{
use HasFactory;
protected $table = 'permissions';
protected $fillable = [
'profile_id',
'user_id'
];
public function user()
{
return $this->belongsTo(User::class);
}
public function profile()
{
return $this->belongsTo(Profile::class);
}
}
Any user can have access to 0 or many profiles
Any profile can have permission given to 0 or many users
On the users.edit blade template I am creating toggle buttons to add/remove profile permissions for the selected user, using the permissions.store and permissions.destroy routes. Creating a new permission is working as expected, however I am having trouble accessing the permission id (marked **** in blade snippet) in order to trigger the destroy function.
User Controller
public function edit(User $user, Profile $profile, Permission $permission)
{
$perm = Permission::where([
['user_id', '=', $user->id],
])->pluck('profile_id', 'id')->toArray();
return view('users.edit', compact('perm'))
->with('user', $user)
->with('profiles', Profile::all());
}
Permission Controller
public function destroy(Permission $permission, User $user, Profile $profile)
{
$permission = Permission::where('user_id', '=', $user->id)
->where('profile_id', '=', $profile->id)
->firstOrFail();
$permission->delete();
return redirect()->back();
}
Blade snippet
#foreach($profiles as $key => $profile)
#if(in_array($profile->id, $perm))
<form action="{{ route('permissions.destroy', **** ) }}" method="POST" >
#csrf
#method('DELETE')
<input type="hidden" value="{{ $user->id }}" name="user_id" id="user_id" />
<input type="hidden" value="{{ $profile->id }}" name="profile_id" id="profile_id" />
<button class="btn btn-primary" type="submit">{{ $profile->profile_name }}</button>
</form>
#else
<form action="{{ route('permissions.store') }}" method="POST" >
#csrf
<input type="hidden" value="{{ $user->id }}" name="user_id" id="user_id" />
<input type="hidden" value="{{ $profile->id }}" name="profile_id" id="profile_id" />
<button class="btn btn-secondary" type="submit">{{ $profile->profile_name }}</button>
</form>
#endif
#endforeach
Thanks in advance
The permission ID is included in the array $perm created in the User controller, but I haven't found a way to call that value and associate it with the permission record so that I can send it to the permission.destroy route.
You can pass the permission ID as a parameter to the route in the action attribute of the form.
To do this, try replacing **** with ['permission' => array_search($profile->id, $perm)].
Here, the array_search() function is used to find the index of the profile ID in the $perm array, and the corresponding permission ID is accessed using that index. This value is then passed as a parameter named permission to the route in the form's action attribute.
I am trying to fetch the parent document with child documents. But getting "Parent filter should not be sent when the schema is nested" error.
Attached the query in below that I have tried but I can't get the solution
q : {!parent which=content_type:person}
fl : *, [child parentFilter=content_type:person]
Below is the document that I have added to solr core.
Collection<SolrInputDocument> batch = new ArrayList<>();
// Parent Doc 1, a person mamed John Jones
SolrInputDocument person1 = new SolrInputDocument();
person1.addField( "id", "john_jones" );
person1.addField( "content_type", "person" );
// "_t" suffix tells Solr that it's text
person1.addField( "first_name_t", "John" );
person1.addField( "last_name_t", "Jones" );
// states and history used in edismax examples
person1.addField( "states_t", "California Nevada Idaho Maine" );
person1.addField( "history_t", "safe accident accident accident accident accident" );
// child docs, the vehicles he owns
SolrInputDocument p1_car1 = new SolrInputDocument();
p1_car1.addField( "id", "jj_car1" );
p1_car1.addField( "content_type", "car" );
// For cars "make" is an alias for "manufacturer"
p1_car1.addField( "make_t", "Honda" );
p1_car1.addField( "model_t", "Accord" );
SolrInputDocument p1_car2 = new SolrInputDocument();
p1_car2.addField( "id", "jj_car2" );
p1_car2.addField( "content_type", "car" );
p1_car2.addField( "make_t", "Nissan" );
p1_car2.addField( "model_t", "Maxima" );
SolrInputDocument p1_bike1 = new SolrInputDocument();
p1_bike1.addField( "id", "jj_bike1" );
p1_bike1.addField( "content_type", "bike" );
p1_bike1.addField( "make_t", "Yamaha" );
p1_bike1.addField( "model_t", "Passion" );
SolrInputDocument p1_bike2 = new SolrInputDocument();
p1_bike2.addField( "id", "jj_bike2" );
p1_bike2.addField( "content_type", "bike" );
p1_bike2.addField( "make_t", "Peugeot" );
p1_bike2.addField( "model_t", "Vivacity" );
// Add children to parent
person1.addChildDocument( p1_car1 );
person1.addChildDocument( p1_car2 );
person1.addChildDocument( p1_bike1 );
person1.addChildDocument( p1_bike2 );
// Add parent to batch
batch.add( person1 );
// Parent Doc 2, person mamed Satish Smith
SolrInputDocument person2 = new SolrInputDocument();
person2.addField( "id", "satish_smith" );
person2.addField( "content_type", "person" );
person2.addField( "first_name_t", "Satish" );
person2.addField( "last_name_t", "Smith" );
person2.addField( "states_t", "California Texas California Maine Vermont Connecticut" );
person2.addField( "history_t", "safe safe safe safe safe safe safe safe accident" );
// Vehicles (child docs)
SolrInputDocument p2_car1 = new SolrInputDocument();
p2_car1.addField( "id", "ss_car1" );
p2_car1.addField( "content_type", "car" );
p2_car1.addField( "make_t", "Peugeot" );
p2_car1.addField( "model_t", "iOn" );
SolrInputDocument p2_bike1 = new SolrInputDocument();
p2_bike1.addField( "id", "ss_bike1" );
p2_bike1.addField( "content_type", "bike" );
p2_bike1.addField( "make_t", "Honda" );
p2_bike1.addField( "model_t", "Spree" );
// link objects and add to batch
person2.addChildDocument( p2_car1 );
person2.addChildDocument( p2_bike1 );
batch.add( person2 );
System.out.println( "Adding batch of " + batch.size() + " parent docs" );
// Submit as a group
patientSolrClient.add( batch );
patientSolrClient.commit()
I was getting same error , and tried all the possibilities described in tutorials, but later i found my managed-schema.xml had a duplicate entry of this.
Auto generated Script:
<fieldType name="_nest_path_" class="solr.NestPathField"
maxCharsForDocValues="-1" omitNorms="true" omitTermFreqAndPositions="true" stored="false" />
Another one manually added by me:
<fieldType name="_nest_path_" type = "_nest_path_" />
I removed my entry then it started working fine.
I was able to resolve this issue by setting the document identifier type to _nest_path_, in your case this appears to be content_type key. Then in the query you no longer need to set the parentFilter param just fl=*,[child] worked for me. You can still add child filters but apparently in Solr8 the documents are stored in a hierarchy and no longer require users to identify the parents.
I figured this out from the Nested Document tickets detailed here: https://issues.apache.org/jira/browse/SOLR-12298
Commenting out the below line worked for me as an intermediate solution (the line is defined in the schema definition of your core).
<field name="_nest_path_" type="_nest_path_"/>
The reason for the exception can be found out through this piece of
Code.
(just grep for the error message "Parent filter should not be sent when the schema is nested" in the code. You should be able to pinpoint the source of this exception.)
Not very sure about the intention/reasoning behind the logic though
i will generate Stacked column chart, which will display on the x-axis cities and on the y-axis are count of genders in column. How to binding chart and this data:
List<Cities> Cities = new List<Cities>()
{
new Cities
{
Name = "Paris",
Genders = new Genders()
{
Man = 350000,
Woman = 436000
}
},
new Cities()
{
Name = "London",
Genders = new Genders()
{
Man = 698056,
Woman = 736982
}
}
};
I am trying to generate Series:
int i = 0;
foreach (var city in Cities)
{
Series s1 = new ColumnSeries();
s1.Title = city.Name;
s1.Name = "S"+i;
StackedColumnChart.Series.Add(s1);
i++;
}
i dont know how to binding data. Thanks
you can try to download a trial version of LightningChart with included demonstration examples for WinForms, WPF with Non-bindable, Semibindable and Fully Bindable examples.
You can easily look at the source code examples, e.g. ExampleStackedBars.
In a code behind you can create a field, which will be binded to the chart BarSeriesCollection property:
public static readonly DependencyProperty BarSeriesProperty =
DependencyProperty.Register(
"BarSeries",
typeof(BarSeriesCollection),
typeof(ExampleStackedBars)
);
public BarSeriesCollection BarSeries
{
get { return GetValue(BarSeriesProperty) as BarSeriesCollection; }
set { SetValue(BarSeriesProperty, value); }
}
And after create a new instance and add data to the collection:
BarSeries = new BarSeriesCollection();
GenerateData();
In XAML you can easily bind it using this line:
<lcusb:LightningChartUltimate.ViewXY>
**<lcusb:ViewXY BarSeries="{Binding BarSeries}">**
<lcusb:ViewXY.BarViewOptions>
<lcusb:BarViewOptions BarSpacing="30" Grouping="ByIndexFitWidth" Stacking="Stack" IndexGroupingFitGroupDistance="20"/>
</lcusb:ViewXY.BarViewOptions>
</lcusb:ViewXY>
</lcusb:LightningChartUltimate.ViewXY>
</lcusb:LightningChartUltimate>
or set binding path in the property tree
Example in Sparrow toolkit is for other chart type. i need Stacked bar chart. My graph must in x-axis cities and for each city must be multiple values in column. This is my chart:
<charting:Chart
Grid.Column="0"
Grid.Row="0"
x:Name="StackedColumnChart"
Title="Stacked Column"
Margin="5">
<charting:StackedColumnSeries>
</charting:StackedColumnSeries>
</charting:Chart>
I dont know what is series. Series is columns? How to assign multiple value (in my example genders) to one column?
I am not sure what's wrong with my date formatting.
I receive the following error:
Error: [ngModel:nonassign] http://errors.angularjs.org/1.3.7/ngModel/nonassign?
profile-edit.html
<input id="birthday" type="date" class="form-control" ng-model="account.birthday | date" datepicker-options="dateOptions" close-text="Close" />
Backend Account Entity:
#Entity
#Table(name = "account")
#JsonIgnoreProperties(ignoreUnknown = true)
public class Account extends BaseEntity implements Serializable {
....
#Column(name = "BIRTHDAY")
private Date birthday;
}
The account.birthday field in debugger seems to hold milliseconds in plain string after the account was fetched from backend.
Right from the debugger:
active: true
birthday: 241912800000
city: "Essen"
country: "Germany"
created: 1450289294000
How do I fix this?
I have used <input type="date" data-ng-model="from_date"> as HTML code and then parsed it in date in Angular as
var var_name = new Date($scope.from_date);
I have a visualForce page and an apex controller. I need to get a date value from my visualForce page into my Apex Controller (this is done already) and then pass this value into my SOQL query. My SOQL query runs fine when I put an actual date value in, but when I use the variable created before it says can't find variable named x.
I'm certain this is a general programming mistake, this is only my second week using code not clicks!
Let me know if you want to see the VF page too.
**Apex Controller***
global with sharing class GoogleChartsController2 {
Opportunity o = new Opportunity();
public Opportunity getProxyObject() {
return o;
}
/**
Loads all Opportunities and then filters
*/
#RemoteAction
global static Opportunity[] loadOpps() {
return [select Id, Name, ExpectedRevenue, LeadSource, DaysToStartDate__c, Probability, CloseDate, Amount from Opportunity WHERE CloseDate = :o.CloseDate ];
}
}
Section from VisualForce Page *
<apex:page controller="GoogleChartsController2" sidebar="false">
<!-- Google API inclusion -->
<apex:includescript id="a" value="https://www.google.com/jsapi">
<apex:sectionheader title="Google Charts + Javascript Remoting" subtitle="Demoing - Opportunities by Exepected Revenue">
<!-- Google Charts will be drawn in this DIV -->
<div id="chartBlock" style="width: 900px; height: 500px;">>
<script type="text/javascript">
// Load the Visualization API and the piechart package.
google.load('visualization', '1.0', {'packages':['corechart']});
// Set a callback to run when the Google Visualization API is loaded.
google.setOnLoadCallback(initCharts);
function initCharts() {
// Following the usual Remoting syntax
// [<namespace>.]<controller>.<method>([params...,] <callbackFunction>(result, event) {...}
// controller : GoogleChartsController
// method : loadOpps
GoogleChartsController2.loadOpps(
function(result, event){
// load Column chart
var visualization = new google.visualization.BubbleChart(document.getElementById('chartBlock'));
// Prepare table model for chart with columns
var data = new google.visualization.DataTable();
data.addColumn('string', 'Opportunity');
data.addColumn('number', 'Days To Contract Start');
data.addColumn('number', 'Probability (%)');
data.addColumn('string', 'Lead Source');
data.addColumn('number', 'Amount');
// add rows from the remoting results
for(var i =0; i<result.length;i++){
var r = result[i];
data.addRow([r.Name, r.DaysToStartDate__c, r.Probability, r.LeadSource, r.Amount]);
}
// all done, lets draw the chart with some options to make it look nice.
visualization.draw(data, {
legend : {position: 'right', textStyle: {color: 'black', fontSize: 10}},
width:window.innerWidth,
length:window.innerLength,
vAxis:{title: 'Probability', textStyle:{fontSize: 10}, minValue: 0, maxValue: 100},
hAxis:{title: 'Days Until Close' , textStyle:{fontSize: 10},
chartArea: {width: '50%', height: '75%'},
sizeAxis: {minSize: 150, minValue: 150},
showTextEvery:1,slantedText:false}})
},
{escape:true});
}
</script>
</div></apex:sectionheader></apex:includescript>
<apex:form >
<apex:outputlabel value="Enter your name here"/>
<apex:inputField value="{!proxyObject.closeDate}"/>
<apex:actionsupport event="onclick" rerender="display" />
<apex:outputpanel id="display">
<apex:outputtext value="The date entered is {!proxyObject.closeDate}"/>
</apex:outputpanel>
</apex:form>
</apex:page>
The need for remoting makes this a bit more interesting. Because remoting methods must be declared as static (as you've already done), you won't be able to reference any member variables that you're using in the controller. You can, however, pass along their value from the page in your remoting call.
First off, you'll want to modify your remoting method to accept a parameter from the Javascript that's calling it. Then you'll just parse that date string in your SOQL query. You can leave the proxyObject in the controller in order to leverage the out-of-the-box date picker that Salesforce provides, but you won't be referencing that variable directly in the loadOpps method.
global with sharing class GoogleChartsController2 {
public Opportunity proxyObject {public get; public set;}
public GoogleChartsController2() {
proxyObject = new Opportunity();
// just giving this a value for testing purposes
proxyObject.CloseDate = System.today();
}
/** Loads all Opportunities and then filters */
#RemoteAction
global static Opportunity[] loadOpps(String closedate) {
return [select Id, Name, ExpectedRevenue, LeadSource, Probability, CloseDate, Amount from Opportunity WHERE CloseDate = :Date.parse(closedate)];
}
}
Next, you're going to have to reference the field on your VF page when making the call to loadOpps. You can do this a couple of different ways, the easiest of which for these circumstances is probably to use the VF $Component merge field markup. This will require you to specify IDs for your nested VF tags:
<apex:form id="testForm" >
<apex:inputField id="closedate" value="{!proxyObject.closeDate}"/>
And these can then be referenced like:
var dt = document.getElementById("{!$Component.testForm.closedate}").value;
So your final VF page becomes something like:
<apex:page controller="GoogleChartsController2" sidebar="false">
<apex:sectionheader title="Google Charts + Javascript Remoting" subtitle="Demoing - Opportunities by Expected Revenue" />
<apex:form id="testForm" >
<apex:outputlabel value="Enter a date here"/>
<apex:inputField id="closedate" value="{!proxyObject.closeDate}" >
<apex:actionsupport event="onchange" rerender="display" />
</apex:inputField>
<apex:outputpanel id="display">
<apex:outputtext value="The date entered is {!proxyObject.closeDate}"/>
</apex:outputpanel>
</apex:form>
<!-- Google API inclusion -->
<apex:includescript id="a" value="https://www.google.com/jsapi">
<!-- Google Charts will be drawn in this DIV -->
<div id="chartBlock" style="width: 900px; height: 500px;">>
<script type="text/javascript">
// Load the Visualization API and the piechart package.
google.load('visualization', '1.0', {'packages':['corechart']});
// Set a callback to run when the Google Visualization API is loaded.
google.setOnLoadCallback(initCharts);
function initCharts() {
// Following the usual Remoting syntax
// [<namespace>.]<controller>.<method>([params...,] <callbackFunction>(result, event) {...}
// controller : GoogleChartsController
// method : loadOpps
var dt = document.getElementById("{!$Component.testForm.closedate}").value;
GoogleChartsController2.loadOpps( dt,
function(result, event){
// load Column chart
var visualization = new google.visualization.BubbleChart(document.getElementById('chartBlock'));
// Prepare table model for chart with columns
var data = new google.visualization.DataTable();
data.addColumn('string', 'Opportunity');
data.addColumn('number', 'Days To Contract Start');
data.addColumn('number', 'Probability (%)');
data.addColumn('string', 'Lead Source');
data.addColumn('number', 'Amount');
// add rows from the remoting results
for(var i =0; i<result.length;i++){
var r = result[i];
data.addRow([r.Name, r.DaysToStartDate__c, r.Probability, r.LeadSource, r.Amount]);
}
// all done, lets draw the chart with some options to make it look nice.
visualization.draw(data, {
legend : {position: 'right', textStyle: {color: 'black', fontSize: 10}},
width:window.innerWidth,
length:window.innerLength,
vAxis:{title: 'Probability', textStyle:{fontSize: 10}, minValue: 0, maxValue: 100},
hAxis:{title: 'Days Until Close' , textStyle:{fontSize: 10},
chartArea: {width: '50%', height: '75%'},
sizeAxis: {minSize: 150, minValue: 150},
showTextEvery:1,slantedText:false}})
},
{escape:true});
}
</script>
</div></apex:includescript>
</apex:page>
This seems to work for the most part for me, although the charting API is complaining about Column 2 being a string...but that's something you should be able to sort out by changing your columns around. Keep in mind that this currently won't re-render the chart whenever you change the date, but that shouldn't be difficult if you make a few changes to your apex:actionSupport tag.
Hope this gets you on the right track!