I am looking for the simplest way to get the referenced item value for a droplink field.
#Html.Sitecore().Field("Alignment")
I want to get the value of the choice, what's the best approach?
If you need to have ability to edit fields of alignment item which is chosen in 'Alignment' droplink field of context item or just show values of alignment item's fields for visitors:
#{
Sitecore.Data.Fields.ReferenceField alignmentField = Sitecore.Context.Item.Fields["Alignment"];
Sitecore.Data.Items.Item alignmentItem = alignmentField.TargetItem;
}
<div>
#Html.Sitecore().Field("Text of Alignment", alignmentItem)
</div>
This example assumes that Alignment template contains 'Text of Alignment' field.
The Droplink field stores the referenced item's ID. To retrieve this ID (providing the field is present in your current item/model):
((LinkField)Model.Item.Fields["Alignment"]).Value
To output the referenced item's name, you could do something like this:
#(Model.Item.Database.GetItem(((LinkField)Model.Item.Fields["Alignment"]).Value).Name)
But that's really ugly. The preferred approach would be to create an extension method encapsulating some of the above so you're not having to re-type that out :D
The article Extending the SitecoreHelper Class by John West shows how to extend the SitecoreHelper class to add custom field renderers, so you could end up creating a neat re-usable snippet like:
#(Html.Sitecore().ReferenceField("Alignment","Name"))
If this is in a partial view i.e. .cshtml file you can also use something like below:
Sitecore.Data.Fields.TextField alignment= Model.Item.Fields["Alignment"];
This will give you the id of the set item in the drop link , then from that id can retrieve it from the database like:
#if (!string.IsNullOrWhiteSpace(alignment.Value))
{
var setAlignment = Sitecore.Context.Database.GetItem(alignment.Value);
if (setAlignment != null && !string.IsNullOrWhiteSpace(setAlignment.Name))
{
setAlignment.Name
}
}
Personally i prefer this way as i can check if the droplink is set before trying to use the value.
Related
How to create edit forms. For url edit?id=1121 I want to display pre-filled data
EditForm(twf.Form):
class child(twf.TableLayout):
name= twf.TextField(name="name",value=DBSession.query(student.name).filter(student.id == <id passed in url>).distinct().all())
#expose ('edit')
def edit(self, id)
return dict(page='edit', , form=EditForm(action='/save')
Template:
<div>${form.display()}</div>
There are a few ways to achieve this, but I'd say that the cleanest one is passing the values to the form from the controller action as showcased by http://turbogears.readthedocs.io/en/latest/turbogears/widgets_forms.html#displaying-forms
In the case of your specific example it should result in having a form that only declares the fields that need editing and a reference to the edited object id:
class EditForm(twf.Form):
class child(twf.TableLayout):
student_id = twf.HiddenField()
name = twf.TextField(name="name")
Then within the controller you can fetch the edited object and provide the values to the form:
#expose('edit')
def edit(self, id):
edited_student = DBSession.query(student).filter(student.id==id).first()
return dict(page='edit',
form=EditForm(action='/save',
value=dict(student_id=id,
name=edited_student.name))
Keep in mind that this is just a proof of concept, I haven't tested the code and it lacks proper validation/error handling. But it should pretty much give the idea that you just pass the student name to the form through the value parameter when displaying it.
I'm not sure what is the way to do this , so here I ask:
I have a Person model and Event model, and a connection table Person_Event.
The interface that I got now works in the following way:
A person is logging in and his id is being send via URL
The person is selecting events he is interested in from the cGridView (checkbox column)
Writing some comment
4.Pressing send button , and the following create action is being triggered:
public function actionXcreate()
{
$model=new Person_Event;
if(isset($_POST['Person_Event']))
{
foreach ($_POST['selectedIds'] as $eventId)
{
$pmodel=new Person_Event;
$pmodel->person_id=$this->_person->id; //the id of the person who is logged in
$pmodel->attributes=$_POST['Person_Event']; //the comment
$pmodel->event_id = $eventId; //all the events he checked in the grid
if (!$pmodel->save()) print_r($pmodel->errors);
}
$this->redirect(array('site/success'));
}
So far , all is logical and simple. However , what I end up is that the comment the person wrote is being duplicated to every person_event row in the DB.
I want to put a text box in each row of the grid , and the commnet that will be written there will go to the specific event.
Now , I found this topic in yii about "admin-panel"
which is kind of helpful , BUT:
I already have a foreach in the action , the one that matches the person's id with the event's id , so how can I put another individual comment for each combo?
The default CGridView supports only basic functionality, you would need to extend CGridView or use an extension to make columns editable
Easiest way to do this is use something like TbEditableColumn from Yii-booster library
see http://yiibooster.clevertech.biz/extendedGridView#gridcolumns EditableColumn in the additional column types section
If you do not like or wish to use twitter-bootstrap styling a standalone extension like http://www.yiiframework.com/extension/eeditable will help.
Alternatively you can extend CGridView yourself to extend it to support column level editing
I have a document in RavenDB that looks looks like:
{
"ItemId": 1,
"Title": "Villa
}
With the following metadata:
Raven-Clr-Type: MyNamespace.Item, MyNamespace
Raven-Entity-Name: Doelkaarten
So I serialized with a type MyNamespace.Item, but gave it my own Raven-Entity-Name, so it get its own collection.
In my code I define an index:
public class DoelkaartenIndex : AbstractIndexCreationTask<Item>
{
public DoelkaartenIndex()
{
// MetadataFor(doc)["Raven-Entity-Name"].ToString() == "Doelkaarten"
Map = items => from item in items
where MetadataFor(item)["Raven-Entity-Name"].ToString() == "Doelkaarten"
select new {Id = item.ItemId, Name = item.Title};
}
}
In the Index it is translated in the "Maps" field to:
docs.Items
.Where(item => item["#metadata"]["Raven-Entity-Name"].ToString() == "Doelkaarten")
.Select(item => new {Id = item.ItemId, Name = item.Title})
A query on the index never gives results.
If the Maps field is manually changed to the code below it works...
from doc in docs
where doc["#metadata"]["Raven-Entity-Name"] == "Doelkaarten"
select new { Id = doc.ItemId, Name=doc.Title };
How is it possible to define in code the index that gives the required result?
RavenDB used: RavenHQ, Build #961
UPDATE:
What I'm doing is the following: I want to use SharePoint as a CMS, and use RavenDB as a ready-only replication of the SharePoint list data. I created a tool to sync from SharePoint lists to RavenDB. I have a generic type Item that I create from a SharePoint list item and that I serialize into RavenDB. So all my docs are of type Item. But they come from different lists with different properties, so I want to be able to differentiate. You propose to differentiate on an additional property, this would perfectly work. But then I will see all list items from all lists in one big Items collection... What would you think to be the best approach to this problem? Or just live with it? I want to use the indexes to create projections from all data in an Item to the actual data that I need.
You can't easily change the name of a collection this way. The server-side will use the Raven-Entity-Name metadata, but the client side will determine the collection name via the conventions registered with the document store. The default convention being to use the type name of the entity.
You can provide your own custom convention by assigning a new function to DocumentStore.Conventions.FindTypeTagName - but it would probably be cumbersome to do that for every entity. You could create a custom attribute to apply to your entities and then write the function to look for and understand that attribute.
Really the simplest way is just to call your entity Doelkaarten instead of Item.
Regarding why the change in indexing works - it's not because of the switch in linq syntax. It's because you said from doc in docs instead of from doc in docs.Items. You probably could have done from doc in docs.Doelkaartens instead of using the where clause. They are equivalent. See this page in the docs for further examples.
I have an observable collection that is exposed to the user by a collectionviewsource. One of the properties on the items in the collection is sortorder. I am trying to allow the user to permanently resort this collection and propagate the changes to the db.
I have the CVS working where I can resort the individual items as they are displayed in the listbox. Now however I have to change the item.sortorder==cvs.currentindex and i am having trouble figuring out the proper way to do this.
EDIT
evidently I was not clear enough. Sortorder is a field in my DB that is part of my object that allows the user to control position of the items as displayed in list controls. I am trying to give my user the ability to change how these items are sorted in the future by changing the value of the sortorder field to equal the current index of the displayed item.
items current sortorder value is 3.
user moves displayed listitem to position 0(ie first position)
items new sortorder=0 item with original sortorder will become 1 etc
this would be achieved by looping through the sorted CVS and making Item.SortOrder= CVS.Item.index
Databases return rows from table based typically on the order they were added to the table unless you specify an order by clause in your query. changing the order in the database is not a good idea. instead, try something such as using a parameterized query and passing in the column and direction you wish to be sorted which is retrieved from a user preference.
I figured it out.
I went back and looked at the code that I was using to change the position of the elements and I am actually using the collection itself:
private void OnDecreaseSortOrderCommandExecute()
{
int index = QuestionsCVS.View.CurrentPosition;
QuestionsViewModel item = SelectedQuestionVM;
if (item != null && index > 0)
{
SortableQuestionsVMCollection.RemoveAt(index);
SortableQuestionsVMCollection.Insert(index - 1, item);
QuestionsCVS.View.Refresh();
QuestionsCVS.View.MoveCurrentTo(item);
}
}
So I simply did this:
private void ResortSortableQuestionsVMCollection()
{
for (int i = 0; i < SortableQuestionsVMCollection.Count; i++)
{
SortableQuestionsVMCollection[i].SortOrder = i;
}
}
I dont know if this will work in every circumstance but it certainly did what I wanted for this one.
I am working on create a custom field type and for implementation issue I need to retrieve the ID of the SPListItem in the SPField class which belong to these field type but I can't retrieve it.
For example:
public class myField:SPFieldText
{
// I need ListItemID in this class
}
Can anyone help me please?
SPFieldText is an SPField, which is the schema definition for a field. Its like saying, given an SQL create table statement, give me the id of row x. Can't be done.
I think the logic you are trying to perform should be done in an event receiver, so say when an item is saved, you take the ID and add it to the text field.
I didn't find a solution but I've tried another solution which is
I can get the ID of the item in the New and Edit forms so I saved the ID and the field value as a one value separated by '/' and in the SPFieldText class I've been able to retrieve the ID value from the value of the field