In SharePoint many fields id-value pairs that are formatting like the following id;#value. This is further complicated with fields like multi-lookup where when extracting the value of that field can yield results like id_1;#value_1;#id_2;#value_2;#id_3;#value_3
I am wondering if there is any known built in function that will simplify this process and at the very least remove the IDs from the value.
Field value objects are stored as strings in the Sharepoint database. For simple values (e.g. "Hello world") this is simple enough. But for complex field values - such as an ID/value pair, how to store the entire value as a single string is obviously more complex as well. Each field value class in Sharepoint is responsible for its own storage implementation. ToString() is responsible for writing a string representation of the value; while the field value's constructor takes a string and is responsible for parsing that and setting all the properties on itself appropriately.
For example, the SPFieldUrlValue (which represents an description) has Url and Description properties. Creating a new SPFieldUrlValue(string fieldValue) object will parse the value and set the properties accordingly.
In order to get a true/correct (and often strongly-typed!) representation of the field value, you must know what type the field is, and what that field's value class is.
The SPField class has many derived classed
For example assuming a Lookup field type (that uses the ID;#value) you can check SPField.Type == SPFieldType.Lookup and then cast SPField to SPFieldLookup and use its overriden methods to get the records value.
See Custom Field Value Classes for more details
Also - If I remember correctly (I can't check this right now so DYOR) you can call .ValueAsText and .ValueAsHtml on the base SPField object and it will remove ID;# from the values.
Related
Quick question.
I have a custom two-option field on an entity, with "Yes"/"No" as the values; "Yes" has the underlying value 1, while "No" has the underlying value 0. I've set the default value for this field to "Yes". However, when I create new entity records, the field always gets the value "No" (0 in the database). It seems to be ignoring the default value I've set. Why?
The field is not present on any of the entity forms, as it's only used in underlying plugin code. Should that matter?
Are you creating a new record for this entity using code that uses the strongly-typed objects? If so, when you create a "new" entity in code, I'm guessing the class itself is setting that field to "false" by default. I don't think those generated classes respect the default values in the metadata. I also think that all fields are submitted on a create when you use these generated classes. That means that your class is setting it to "no" by default and then on create, the system thinks that you explicitly set it to "no" so default values are not applied. I think you need to explicitly remove that attribute from the attribute collection of your entity before you create it. That way the system should respect the default value on create. Sorry for all the "I thinks" but I'm not in a place that I can test or verify all of this. :)
In a JSF page I have to display the data from an entity.
This entity has some int fields which cannot be displayed directly but need to be translated into a descriptive string.
Between them some can have a limited number of values, others have lots of possible values (such as a wordlwide Country_ID) and deserve a table on the Db with the association (ID, description).
This latter case can easily be solved navigating via relationship from the original entity to the entity corresponding to the dictionary table (ID, description) but I don't want to introduce new entities just to solve translations form ID to description.
Besides another integer field has special needs: the hundred thousand number should be changed with a letter according to a rule such as 100015 -> A00015, 301023 -> C01023.
Initially I put the translation code inside the entity itself but I know the great limits and drawbacks of this solution.
Then I created a singletone (EntityTranslator) with all the methods to translate the different fields. For cases where the field values are a lot I put them inside a table which is loaded from the singletone and transformed in a TreeMap, otherwise the descriptions are in arrays inside the class.
In the ManagedBean I wrote a getter for EntityTranslator and inside the jsf I use quite long el statements like the following:
#{myManagedBean.entityTranslator.translateCountryID(myManagedBean.selectedEntity.countryID)}
I think the problem is quite general and I'm looking for a standard way to solve it but, as already stated, I don't want to create new 'stupid' entities only to associate an ID to a description, I think it is overkill.
Another possibility is the use of converters Object(Integer) <-> String but I'm more comfortable in having all the translation needs for an Entity inside the same class.
Your question boils down to the following simple line:
How can I display a field different from id of my entity in my view and how can I morph an integer field into something more meaningful.
The answer is that it depends on a situation.
If you solely want to input/output data, you don't need id at all apart from the possible view parameter like ?id=12345. In this case you can input/output anything you want in your view: the id is always there.
If you want to create a new entity most possibly you have a way of generating ids via JPA, or database, or elsehow besides the direct input from the user. In this situation you don't need to mess with ids as well.
If you want to use information on other entities like show user a dropdown box with e.g. a list of countries, you always have the option to separate label (let it be name) and value (let it be id), or even have a unique not null column containing the country name in your database table that will serve as a natural identifier. If you'd like to get data from the user using an input text field you always can create a converter that will do the job of transforming user input strings to actual entity objects.
Regarding the transformation of your integers, you've actually got several choices: the first one is to attach a converter for these fields that will roughly do 301023 -> C01023 and C01023 -> 301023 transformations, the second one is to write a custom EL function and the third one is to prepare the right model beforehand / do the transformations on-the-fly.
I am having trouble posting a form that contains a Dictionary that contains an int as a key and a list of objects as a value.
Originally this was just a List of Objects and that worked fine and the type was:
List<MyObject> Fields
the working markup was
Fields_{0}__Property1
where {0} is the index of the object. To get it to post back the List of Objects I rendered the object with hidden fields like this:
#Html.HiddenFor(m => m.Property1, new { Name = string.Format("Fields[{0}].Property1", Model.Index), #id = string.Format("Fields_{0}__Property1", Model.Index) })
This worked well. Now however, we have a dictionary instead of a list and the list is inside the dictionary.
Now the type is:
Dictionary<int, List<MyObject>>.
I tested the format expected when we render the dictionary using Html.HiddenFor and so I've added hidden fields with the required format which now is:
#Html.HiddenFor(m => m.Property1, new { Name = string.Format("Fields[{0}][{1}].Property1", Model.Index, Model.Position), #id = string.Format("Fields_{0}__{1}__Property1", Model.Index, Model.Position) })
now the field id is
Fields_{0}__{1}__Property1
where {0} is the key of the dictionary and {1} is the index of the object in the list.
However on postback I now get
[InvalidCastException: Specified cast is not valid.]
System.Web.Mvc.CollectionHelpers.ReplaceDictionaryImpl(IDictionary`2 dictionary, IEnumerable`1 newContents) +131
I am guessing MVC is smart enough to render the fields of this complex object on the view but not smart enough to collect them back into the viewmodel when we post back.
I found this other guy who had a similar problem here and he solved it by not using a dictionary but instead creating a complex object. I'm wondering, however, if there's a quicker way that won't require me to rewrite the entire system.
Any ideas?
Update
I solved it by taking the source code of DefaultModelBinder and adjusting it.
I found the source here. I didn't create my own Binder because I want all the advanced functionality and validation rules to apply to all other elements.
Once I got the DefaultModelBinder compiling and working I found the part where the dictionary was failing to cast the complex items and wrote a custom Dictionary update method that solved the problem
You can always create a custom Model Binder to bind objects from request values exactly as you want. Simply create a class that implements the System.Web.Mvc.IModelBinder interface and implement the BindModel() method.
Hashtable iHashtable=new Hashtable();
iHashtable.put("Name", "Jhon");
iHashtable.put("Address","India");
Enumeration iEnumeration=iHashtable.keys();
while(iEnumeration.hasMoreElements())
{
Object iresult1=iEnumeration.nextElement();
String iresult2=(String) iHashtable.get(iresult1);
System.out.println(iresult1);
System.out.println(iresult2);
My problem is I want to put the value at LWUIT table dynamically using the HashTable key and value,here is iresult1 and iresult2,using the key and value I want to create the LWUIT table where the value will be shown in the following form.
Name Jhon
Address India
please help me with the source code because i am new in J2me Application.please remember don't hardcore the key and value ,we get the value after parsing.
You can't do that since the JSON data isn't tabular but rather a hierarchy of nested hashtables and vectors based on the response from the server.
You can show the JSON data as a tree though by implementing the tree model interface, its not trivial but not too hard. You just need to return key objects for the keys (instead of strings) so they will allow including a reference to the value element.
In my JSF page, I have a <rich:autocomplete/> which must be filled by selecting an object from the list. The id of the object does not have useful meaning, so I have to write a Converter to change it to readable string.
Unfortunately the string representation of the object could not uniquely identify different objects and so the conversion is not reversible. Now I want to know how I could solve this problem? Is it possible to store the id of the selected object into a <h:inputHidden> and pass it to the view scoped backing bean?
You're using the input component and the converter the wrong way. You are apparently using the object's string representation (the item label) as input value, while you should be using the object's unique identifier (the item value) as input value. The converter is merely to convert between the custom object and the unique identifier, not between the custom object and the string representation.
I have searched this and until the moment there are no direct solution provided by the rich:component as it does not has itemValue like rich:select
Also there are 2 workaround solution.
to use JavaScript to add the id value of the selected item to a
hidden field and then use this hidden field to identify the
selected item
I used the fetchValue attribute to concat item_id - item_name
then I created a converter which substring the item_id to identify
the selected item.