Silverstripe 3.1 page has_one belongs_many dataobject - silverstripe

I have a class ProductPage extends Page and a class ProductSpecifications extends DataObject. Can I create a $has_one relationship to the Dataobject and a $belongs_to back to the ProductPage? (I know it's easier just to keep all the data associated to the page but I would prefer the ProductSpecifications as a separate dataobject). If so how do I access the CMSfields of the Dataobject from the Page? Gridfield? Or something like
$fieldsToAdd = ProductSpecifications::create();
$fieldsToAdd->getCMSFields();
$fields->addFieldsToTab('Root.Specifications', $fieldsToAdd);

You're speaking of a 1:1 relation? Then the heading of the question is a bit misleading.
You can edit a has_one "inline" using the has one edit module
hope that helps, wmk

Related

Views and Fragments

I have been reading about fragments lately, and almost everyone says that we should use it. I still can't understand the concept very well. I have read this, but I still have some questions.
First: A fragment must be related ( if its the right word) to an activity, let say MainActivity, the fragment has its own layout, the MainActivity has its own two. So what will be displayed on the screen? the fragment layout or the MainActivity or Both??
Second: If I want to convert an existing code to use fragments, what are the main changes?
Third: If I want to have more than one fragment, do I have to add a class that extends Fragment for each fragment I want to create??
Forth: onCreateView of the class that extends Fragment returns a view, is it correct to create a view inside it and return it for the main activity to add it to its layout??
Any help is appreciated.
Here are some tips about fragments what i understand so far , it might help you to understand Fragments :
1: About your first Question, yes both(Activity and Fragment) has their own layouts but Activity layout is act as base layout for fragments but this also depends on the layout you are working. If i state a simple example of HelloWorld app(which automatically created when you first create your Project in eclipse in updated adt), then you saw there Activity act as base and fragment layout show over it.
2: If you want to change the existing code to use fragments,firstly it depends upon the complexity of your code, and after that you have to change various things like if you are supporting api level 10 and below than you have to use Extra Libraries.there are lots of changes to be made but these all depends on your requirements.
3: Yes you have to create a Class which extends Fragment or any other Sub Class of Fragment. This Class is just like your Activity Class in which you have a xml layout to work with.
4: Yes you have to define a view inside OnCreateView() to return it to the activity to add to its layout or to show the UI.
Fragments are just like Activities , the pain comes when you working with Nested Fragments. and the life cycle of fragments are little different than Activity .
Note :please tell me if you have other queries or in case of any doubt about above written statements.
First:
In the layout of MainActivity you can embed multiple fragments layouts. You can even reuse these fragment layouts in any other activity. Ah, Good feature!
Second:
If I want to convert an existing code to use fragments, what are the
main changes?
To use fragments in your existing code you just need to,
The fragments will be added to the activity using the <fragment> element in the layout or can be added dynamically.
To check if the fragment is already part of your layout you can use the FragmentManager class -
DetailFragment fragment = (DetailFragment) getFragmentManager().
findFragmentById(R.id.detail_frag);
if (fragment==null || ! fragment.isInLayout()) {
// start new Activity
}
else {
fragment.update(...);
}
If a fragment is defined in an XML layout file, the android:name attribute points to the corresponding class.
To dynamically add fragments to an existing layout you typically define a container in the XML layout file in which you add a Fragment.
For this you can use, for example, a FrameLayout element.
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.your_placehodler, new YourFragment());
ft.commit();
A new Fragment will replace an existing Fragment that was previously added to the container.
If you want to add the transaction to the backstack of Android, you use the addToBackStack() method.
This will add the action to the history stack of the activity, i.e., this will allow to revert the Fragment changes via the back button.
Third:
If I want to have more than one fragment, do I have to add a class
that extends Fragment for each fragment I want to create??
To define a new fragment you either extend the android.app.Fragment class or one of its subclasses,
for example, ListFragment, DialogFragment, PreferenceFragment or WebViewFragment.
Forth:
onCreateView of the class that extends Fragment returns a view, is it
correct to create a view inside it and return it for the main activity
to add it to its layout??
No need to return it to the main activity to add it to its layout. Just use FragmentTransaction's replace inside Main Activity followed by commit to be done.

Symfony2 - Saving child and parent from the same form

I'm new to Symfony2 and i've been struggling with an issue handling a form submission. I can't help feeling i'm missing something stupid, but after googling and not findind any solutions I thought i'd post my problem here.
So, I have a form to create a child entity and edit a couple fields on a parent entity. To build the form i've used the FormBuilder, where i added two form types (one for the child and one for the parent). The parent type includes the ID field for the parent.
On the action that handles the form submission i'm calling handleRequest which fails because:
Neither the property "id" nor one of the methods "setId()", "_set()" or "_call()" exist and have public access in class "Ahms\MyBundle\Entity\Parent".
This happens when the parent id field is part of the form, when it's not part of the form this runs smoothly.
What am I missing?
Thanks!
If you create the Form from child Controller, you have to declare id in child class and have to writ public function setId($id) and public function getId() method.

Hiding dexterity field according user property

While adding dexterity object, I have two fields in which we like to display only one field according to user property which is saved in members data.
Schema definition is somewhat like:
class IMyApplication(form.schema):
fieldA = schema.textline(...)
fieldB = schema.textline(...)
I would like to show one fields out of these two field to user according to their user property.
Many thanks in advance for guide/link/advise .
First please consider the example for a custom add/edit form in the DX-docu
Then you are able to hide a field in the updateWidgets method of the form.
Example Code (not tested):
from plone.dexterity.browser.add import DefaultAddForm
from z3c.form import interfaces
class AddForm(DefaultAddForm):
def updateWidgets(self):
super(AddForm, self).updateWidgets()
if my_condition:
self.widgets['myfield'].mode = interfaces.HIDDEN_MODE
Since you have to do the same in the add and edit form, you could create a mixin class with your customization.

Dynamically add different user controls

I'm working on a website that will allow instructors to report on the academic progress of students in their classes. I've got the website set up two primary pages: one with a user control that displays the classes (a GridView of basic class info with a child GridView in a template field that displays student names and checkboxes to select them -- called MiniStudents), and another with a user control that displays the selected students -- called FullStudents.
Although improbable, it's possible that an instructor could have the same student in two separate classes. I've already accounted for this in the current page setup -- the combination of student ID and class ID (class IDs change each quarter, for those thinking this will be an issue) form a unique key within the database. Recently, one of my users asked if I could break records out by classes on the page, so that instructors would be able easily recognize which class they're operating in.
So, my question is this: is it possible for me to dynamically add a column to the end of the class user control that would allow me to switch out MiniStudents for FullStudents?
If I've left out any important details or if anyone wants/needs code, please let me know.
Try this:
//Under page_load
string path;
if(condition) path = "~/MiniStudents.ascx";
else path = "~/FullStudents.ascx";
Control userControl = this.LoadControl(path);
panel1.Controls.Add(userControl);
And if you have specific properties that you want to set before the usercontrol gets rendered then make them inherit a custom usercontrol class:
public class CustomControl : UserControl
public class MiniStudents : CustomControl
public class FullStudents : CustomControl
So then you can do this:
CustomControl userControl = (CustomControl)this.LoadControl(path);
userControl.UserId = userId;
I hope this helps!
You could add both, and hide one or the other.
You could use a multiview control to control which control is visible. Though I would be concerned about your viewstate size if you are loading all these controls simulantously. It sounds like there could be a lot of data and markup on the page.

can we inherit more then on class in asp.net aspx page?

I want to inherit more than one class is there any method?
For instance in login.aspx page:
<%# page language="c#" codefile="nishant.aspx.cs" autowireup="true" inherit="nishant"%>
now code behind file
nishant.aspx.cs:
class nishant
{
//code...
}
class bill
{
//code.....
}
Now, I want to inherit bill class then how I will ?
.NET does not support multiple inheritance, this includes asp.net, so no, this is not possible.
You can have your nishant class inherit from the bill class or the other way around, if you want to share functionality. You page can then inherit from the inheriting class and access the functionality of both.
Another option is to inherit from one class and implement an interface (or several interfaces), but the fact that you can implement more than one interface is not the same as multiple inheritance.
There are other things that can be done, depending on what exactly you are trying to achieve (I am primarily thinking about composition versus inheritance).
Multiple inheritance is not allowed. The only way is:
public class Bill : Page
{ }
public class Nishant : Bill
{ }
But rather you should think about your design. Such approach is usually not needed.
No. By nature, .Net allows only single inheritance. At best you could implement an interface, but you will still have to have the code in your nishant class or extract the functionality into your bill class and make function calls.
Although in the case you mention, this is not actually multiple inheritance. Your nishant class must be of type System.Web.UI.Page. So if you create a library with a "bill class", you can then inherit it.
public class bill : System.Web.UI.Page
{
// Your custom code
}
///
public class nishant : bill
{
}
.NET does not support multiple inheritance (one class that inherit from two or more classes).
However you can have as many parent class as you want. Have a look at the decorator pattern.
Or use interfaces, you can have more than one.
In short: implement interfaces and use extension methods
Implementing interfaces might be the way to go, really depends on the functionality you want to inherit.
You can read about inheritance and interfaces here: http://msdn.microsoft.com/en-us/library/ms973861.aspx
When you implement interfaces, but don't want to duplicate the same code into every class that implements a certain interface, you can also write extension methods for the interfaces. Read more about extension methods here: http://msdn.microsoft.com/en-us/library/bb384936.aspx

Resources