I'm facing a silly issue of the default value not being rendered in the form.
In my app, when the user is logged in, a form will be auto-filled with some of the details as it will fetch the data from the stored user information passed to my component through props.
In that case, my already selected 'Gender' i.e. the default value is not getting displayed when the component is rendered.
At the same time, when I passing the same value as hard-coded, it works perfectly fine.
I'm receiving the 'defaultValue' in 'renderGenderDropDown' as 'Male'(same as I stored in myValue const).
But, myValue const works, defaultValue doesn't.
And yes, my component is used in multiple other components and works perfectly fine. It basically, renders '' from 'React'.
What do I need to fix this?
Code:
renderGender() {
const { options, data } = this.props;
const gender = get(data, 'gender');
const defaultValue = gender ? capitalize(gender) : gender;
const fieldName = 'gender';
return this.renderGenderDropDown(fieldName, defaultValue, prefixOptions);
}
renderGenderDropDown(fieldName, defaultValue, options) {
const { configuration, id, validations } = this.props;
const myValue = 'Male';
return <AppDropDown
label={getLabel(fieldName, configuration, validations, 'gender')}
options={dropdownOptions}
defaultValue={myValue}
//defaultValue={defaultValue}
key={fieldName}
className={fieldName}
disabled={false}
id={id}
onChange={this.onGenderChange(this[fieldName])}
/>
}
In Javascript, there isnt a native capitalize() . This is probably returning back undefined instead of a string. Try this to capitalize the first letter in the string.
gender.charAt(0).toUpperCase() + gender.substr(1)
Related
I have this code below which will allow me to get the user selected option but the problem i couldn't access the local variable ,
the code is below
let gender=""
const handleAddrTypeChange = (e) => {
console.log((addrtype[e.target.value]))
gender =addrtype[e.target.value]
}
console.log(gender)
What I'm looking for is reading the value gender which is actually undefined
Any help is welcome,
Best Regards
If you wish to have a 'variable' and update it based on an action, and then use the updated value elsewhere, you should use state
const [gender, setGender] = useState('');
const handleAddrTypeChange = (e) => {
console.log((addrtype[e.target.value]))
setGender(addrtype[e.target.value])
}
console.log(gender)
updating a components state will rerender the component with the new value for gender. Setting a variable like in your example will not rerender the component
Using code, I am trying to create a "Widget" Content-Type called FeaturedProperties with an editable field called MaxVisibleField. I want the MaxVisibleField field to show up under the Fields section when editing the content-type.
I used migration to create a new Contact-Part called MaxPropertiesToShow and created a field called MaxVisibleField for the MaxPropertiesToShow part.
I am expecting the MaxVisibleField field to show up when the “Widget” is edited in the admin panel. When I edit the FeaturedProperties content-type, I see no fields listed. However, I do see the part.
What else do I need to do to make my field MaxVisibleField show up when my Widget is being edited?
Here is my migration code
public int Create()
{
_contentDefinitionManager.AlterPartDefinition("MaxPropertiesToShow", (part) =>
{
part.WithField("MaxVisibleField", c =>
{
c.OfType(nameof(NumericField))
.WithDisplayName("Max Properties To Show")
.WithDescription("The app with display up to this many properties")
.WithSettings(new NumericFieldSettings()
{
Required = true,
Maximum = 50,
DefaultValue = "8",
});
});
});
_contentDefinitionManager.AlterTypeDefinition("FeaturedProperties", (type) =>
{
type.Stereotype("Widget")
.Creatable(false)
.Listable(false)
.Versionable(false)
.WithPart(nameof(FeaturedPropertyPart));
});
return 1;
}
Here is a screenshot of what I am seeing
Also, in the Widget-FeaturedProperties.cshtml view, how can I render the title in a place I want it to show up instead of the standard position the app displays it in?
tables in my EntityFramework model are events, eventtypes, subevents, subeventtypes
using the MVC5 builders (right click on controllers, add, add controller) I created controllers and views for the last three tables without issue however when I create the controller and views for the events entity I produce the following errors
Keyword, identifier, or string expected after verbatim specifier: #
'EventType' is a type, which is not valid in the given context
the code that was generated in the event controller is
{
private Entities db = new Entities();
// GET: Events
public ActionResult Index()
{
var events = db.Events.Include(# => #.EventType); ERROR HERE
return View(events.ToList());
}
any help with this issue would be greatly appreciated
TIA
I experienced the same issue when using the "MVC Controller with views, using Entity Framework" template.
var #group = await _context.Groups
.Include(# => #.Company)
.FirstOrDefaultAsync(m => m.GroupId == id);
My workaround was simple to replace the # symbol with another character i.e. g
var #group = await _context.Groups
.Include(g => g.Company)
.FirstOrDefaultAsync(m => m.GroupId == id);
I am building an Angular 1.5 component that wraps Chosen list, which needs to be initialized by calling .chosen() on the jQuery element. I can do that using the $postLink lifecycle callback, and something like $('.chosen-select').chosen(), which works fine. However, I can anticipate someone using multiple instances of the component on the same page, so using a class selector would not necessarily get the component you want.
I tried using an id selector instead, by adding a prefix to whatever id someone assigns to the component in HTML. For example, I may use the component like <chosen-select id="roles"></chosen-select> and in the template if have <select id="cs-{{$ctrl.id}}"> (in the controller, I bind id: '#'). This all works as expected EXCEPT that in $postLink, the select element has been created (and other bindings, such as the one that lists options, resolved) but id is still "cs-{{$ctrl.id}}". At what point does that become "cs-roles" (which is what it is in the DOM when everything has been set up)? What is the best way to ensure that I am accessing the object that belongs to this component?
Here is the component code, which works:
template:
<select id="cs-{{$ctrl.id}}" class="chosen-select"
ng-options="(option.name || option) for option in $ctrl.options track by (option.id || option)"
ng-model="$ctrl.result"
>
</select>
component:
mymod.component('chosenSelect', {
templateUrl: 'shared/components/chosenSelectComponent.html',
controller: chosenSelectController,
bindings: {
id: '#',
options: '<',
config: '<?',
selected: '<?',
doChange: '&?'
}
});
function chosenSelectController() {
var vm = this;
vm.result = vm.selected || vm.options[0];
vm.$postLink = function() {
// would like to use ("#cscomp-" + vm.id) to make sure it is unique,
// but id doesn't seem to have been resolved yet in select element
$(".chosen-select")
.chosen(vm.config)
.on('change', function(evt, params) {
// parms.selected also holds result
vm.doChange({ value: vm.result });
});
};
}
I realized I could use a hierarchical selector to solve the problem. In the $postLink function, referencing $("#" + vm.id + " .chosen-select") does exactly what I want it to by narrowing the selection to only elements that are descendants of the element with the specified id.
My module creates a custom content item through the controller:
private ContentItem createContentItem()
{
// Add the field
_contentDefinitionManager.AlterPartDefinition(
"TestType",
cfg => cfg
.WithField(
"NewField",
f => f
.OfType(typeof(BooleanField).Name)
.WithDisplayName("New Field"))
);
// Not sure if this is needed
_contentDefinitionManager.AlterTypeDefinition(
"TestType",
cfg => cfg
.WithPart("TestType")
);
// Create new TestType item
var newItem = _contentManager.New("TestType");
_contentManager.Create(TestItem, VersionOptions.Published);
// Set the added boolean field to true
BooleanField newField = ((dynamic)newItem).TestType.NewField as BooleanField;
newField.Value = true;
// Set title (as date created, for convenience)
var time = DateTime.Now.ToString("MM-dd-yyyy h:mm:ss tt", CultureInfo.InvariantCulture).Replace(':', '.');
newItem.As<TitlePart>().Title = time;
return newItem;
}
The end result of this is a new TestType item with a field that's set to true. Viewing the content item in the dashboard as well as examining ContentItemVersionRecord in the database confirms that the value was set correctly.
However, queries don't seem to work properly on fields that are set in this manner. I found the record IntegerFieldIndexRecord, which is what I assume projections use to fill query result pages. On this, the value of TestField remains at 0 (false), instead of 1 (true).
Going to the content item edit page and simply clicking 'save' updates IntegerFieldIndexRecord correctly, meaning that the value is now picked up by the query. How can the record be updated for field values set programmatically?
Relevant section of migration:
SchemaBuilder.CreateTable(typeof(TestTypePartRecord).Name, table => table
.ContentPartRecord()
);
ContentDefinitionManager.AlterTypeDefinition(
"TestType",
cfg => cfg
.DisplayedAs("Test Type")
.WithPart(typeof(TitlePart).Name)
.WithPart(typeof(ContainablePart).Name)
.WithPart(typeof(CommonPart).Name)
.WithPart(typeof(IdentityPart).Name)
);
Edit: The fix for this is to manually change the projection index record whenever changing a field value, using this call:
_fieldIndexService.Set(testResultItem.As<FieldIndexPart>(),
"TestType", // Resolves as TestTypePart, which holds the field
"newField",
"", // Not sure why value name should be empty, but whatever
true, // The value to be set goes here
typeof(bool));
In some cases a simple contentManager.Publish() won't do.
I've had a similar problem some time ago and actually implemented a simple helper service to tackle this problem; here's an excerpt:
public T GetStringFieldValues<T>(ContentPart contentPart, string fieldName)
{
var fieldIndexPart = contentPart.ContentItem.As<FieldIndexPart>();
var partName = contentPart.PartDefinition.Name;
return this.fieldIndexService.Get<T>(fieldIndexPart, partName, fieldName, string.Empty);
}
private void SetStringFieldValue(ContentPart contentPart, string fieldName, IEnumerable<int> ids)
{
var fieldIndexPart = contentPart.ContentItem.As<FieldIndexPart>();
var partName = contentPart.PartDefinition.Name;
var encodedValues = "{" + string.Join("},{", ids) + "}";
this.fieldIndexService.Set(fieldIndexPart, partName, fieldName, string.Empty, encodedValues, typeof(string));
}
I've actually built this for use with MediaLibrary- and ContentPicker fields (they encode their value as string internally), so it might not be suitable for the boolean field in your example.
But it can't be that hard to implement, just look at the existing drivers and handlers for those fields.
There are 2 ways to fix this:
1) Ensure the newly created item is getting published by calling ContentManager.Publish() as Orchard.Projections.Handlers.FieldIndexPartHandler listens to the publish event to update the FieldIndexPartRecord
2) use IFieldIndexService to update FieldIndexPartRecord manually, see implementation of Orchard.Projections.Handlers.FieldIndexPartHandler to get in idea how to do this
Hope this helps.
:edit
Due to calling Create(...Published) the ContentManager.Published() won't do anything as the item is already considered published.
You can do the following to force the publish logic to run:
bool itemPublished = newItem.VersionRecord.Published;
// unpublish item first when it is already published as ContentManager.Publish() internally first checks for published flag and when set it aborts silently
// -> this behaviour prevents calling publish listeners
if (itemPublished)
_contentManager.Unpublish(newItem);
// the following call will result in calls to IContentHandler.Publishing() / IContentHandler.Published()
_contentManager.Publish(newItem);
or just create the item as a draft and publish it when everything is setup correctly.