Coldfusion ORM confusion: Repeated column in mapping for entity: - orm

I am just starting out using ORM and I'm running into confusion.
Here is my error:
Error Occurred While Processing Request
Repeated column in mapping for entity: skill column: programTypeID (should be mapped with insert="false" update="false")
Here is a basic scenario I am using:
TABLES:
**ProgramType**
programTypeID (PK)
programType varchar(50)
**Skill**
skillID (PK)
Skill varchar(50)
programTypeID(int) (FK)
From my understanding my skill - programtype relationship is a many-to-one... Meaning Many Skills can only have 1 program Type... or 1 program type can be mapped to many skills.
Skill.cfc:
<cfcomponent persistent="true">
<cfproperty name="skillid" fieldType="id" generator="identity">
<cfproperty name="skill" ormType="string">
<cfproperty name="programTypeID" ormType="integer">
<cfproperty name="programType" fieldtype="many-to-one" fkcolumn="programTypeID" cfc="programType">
</cfcomponent>
ProgramType.cfc
<cfcomponent persistent="true" table="programtype">
<cfproperty name="programtypeid" fieldType="id" generator="identity">
<cfproperty name="programtype" ormType="string">
<cfproperty name="skill" fieldType="one-to-many" type="array" cfc="skill" fkcolumn="programTypeID" inverse="true">
</cfcomponent>
SkillEditForm.cfm
<cfoutput>
<form class="form-horizontal" action="submit.cfm" method="post">
<input name="skillid" type="hidden" value="#skill.getSkillid()#">
<div class="control-group">
<label class="control-label" for="programTypeID">Skill</label>
:
<div class="controls">
<select name="programTypeID">
<cfloop index="programType" array="#programTypes#">
<option value="#programType.getProgramTypeID()#"
<cfif programType.getProgramtypeid() eq skillProgramType.getProgramTypeid()>selected</cfif>
>#programType.getProgramType()#</option>
</cfloop>
</select>
</div>
</div>
<div class="control-group">
<label class="control-label" for="skill">Skill</label>
:
<div class="controls">
<input type="text" id="skill" placeholder="" name="skill" value="#skill.getSkill()#">
</div>
</div>
<div class="control-group">
<div class="controls">
<button type="submit" class="btn">Submit</button>
</div>
</div>
</form>
</cfoutput>
I find that if I remove programTypeID from the skill.cfc my error goes away. But, my confusion runs in, if programTYpeID is not defined in my CFC, when I go to add or update my entity on the submit.cfc page... how will I set the programTypeID from my select box on the form?

You need to remove the programTypeId property, otherwise you will have 2 columns with that name as the relationship you define will create one.
You would first need to grab the program type that matches the ID passed in and then set that value in the Skill object such as (this assumes you have already created a Skill object)
var programType = entityLoadByPK( 'programType', form.programTypeId)
skill.setProgramType( programType )
As part of validation, you would also want to make sure that the programType is not null before trying to save.

Related

Razor Reusable Form View With Data Annotations

We're using ASP.NET Core 3.1 with Razor to render many Twitter Bootstrap html forms, each with it's own model. Data Annotations are used for server and client side validation.
We have tried to create a generic, reusable partial view / component / tag helper / etc to render the same html for all fields, but found none of the method working.
Consider the following fields with data annotations:
[BindProperty, Required(ErrorMessage = "Field is required"), RegularExpression("[^\\s]+", ErrorMessage = "No spaces allowed")]
public string FirstName { get; set; }
[BindProperty, Required(ErrorMessage = "Field is required")]
public string LastName { get; set; }
[BindProperty] [EmailAddress(ErrorMessage = "Invalid e-mailaddress")]
public string Emailaddress { get; set; }
Each field should render the following html:
<div class="form-group row">
<label class="col-md-4 control-label" asp-for="FirstName/LastName/Emailaddress">
Your first name / last name / e-mailaddress
</label>
<div class="col-md-4">
<input asp-for="FirstName/LastName/Emailaddress" class="form-control input-md" />
<span class="invalid-feedback" asp-validation-for="FirstName/LastName/Emailaddress"></span>
</div>
</div>
The goal is to be able to create a simple Razor page, such as (or any other method):
<form method="Post">
<partial name="partialFormTextInput for="FirstName" />
<partial name="partialFormTextInput for="LastName" />
<partial name="partialFormTextInput for="Emailaddress" />
<input type="submit" value="Submit form">
</form>
It would greatly simplify the process of creating forms for different models. We have found that the primary issue is in the data annotations, as they do not render in partial views, nor in tag helpers.
Has anyone succeeded in creating this?
Update
If a partial view is used, the actual (simplified) result is:
<input type="text" id="FirstName" name="FirstName" value="">
<span class="invalid-feedback field-validation-valid" data-valmsg-for="FirstName" data-valmsg-replace="true"></span>
While the expected result is:
<input type="text" class="form-control input-md" data-val="true" data-val-regex="No spaces allowed" data-val-regex-pattern="[^\s]+" data-val-required="Field is required" id="FirstName" name="FirstName" value="">
<span class="invalid-feedback field-validation-valid" data-valmsg-for="FirstName" data-valmsg-replace="true"></span>
The data-val* attributes are missing on the input

Using ref in a repetitive environment

I'm using a custom element to print the length of an input element. I got it working in a regular environment, but I have trouble creating unique refs in a repeat.for environment
I've tried using combinations of ref=name$index or ref=name${$index}, but none of them work so far.
In a non-repetitive environment, this works
<div class="row">
<label>
Name
<my-custom-element field.bind="name"></my-custom-element>
<input
type="text"
name="name"
ref="name"
value.bind="name"
maxlength="150" />
</label>
</div>
However, once I use repeat for, it stops working, cause I am using field.bind and ref wrongly. E.g.
<div repeat.for="item of items" class="row">
<label>
Name
<my-custom-element field.bind="name${$index}"></my-custom-element>
<input
type="text"
name="name${$index}"
ref="name${$index}"
value.bind="item.name"
maxlength="150" />
</label>
</div>
I'm just trying to make the ref look something like name0, name1, name2 etc, so that it is unique.
The error looks like Parser Error: Unconsumed token { at column 5 in expression [name${$index}]
You are iterating through items, which presumably is an array of objects having a name property. I think you want something more like the following:
<div repeat.for="item of items" class="row">
<label>
Name
<my-custom-element field.bind="item.name"></my-custom-element>
<input
type="text"
name="item.name"
ref="item.name"
value.bind="item.name"
maxlength="150" />
</label>

reference variable in ngFor not working

I want to convert following HTML code to Angular code using *ngFor
<div>Children: <input type="radio" id="1" name="children" [value]="1" [(ngModel)]="this.children"/>1
<input type="radio" id="2" name="children" [value]="2" [(ngModel)]="this.children"/>2
<input type="radio" id="3" name="children" [value]="3" [(ngModel)]="this.children"/>3
You have {{this.children}} children
</div>
Angular code
<div>Children: <input *ngFor = "let option of selectOptions" type="radio" id=option name="children" [value]=option [(ngModel)]="this.children"/>{{option}}
You have {{this.children}} children
</div>
selectOptions is defined in Component's class as follows:
selectOptions:Array<number>=[1,2,3]
I can see error for {{option}} that Angular: Identifier 'option' is not defined. The component declaration, template variable declarations, and element references do not contain such a member
I also see error for id=option name="children" that tag start is not closed.
What am I doing wrong?
I used your code like this:
<div>Children: <input *ngFor = "let option of selectOptions" type="radio" id={{option}} name="children" [value]=option />{{option}}
You have {{this.children}} children
</div>
It worked with this result:
Generated this html:
It seems one issue is that option goes out of scope once input tag is closed. If I move *ngFor to div then I get the labels. But they are now displayed vertically, not horizontally. This code works but with vertical alignment <div *ngFor = "let option of selectOptions"> <input type="radio" [id]="option" name="children" [value]=option [(ngModel)]="this.children">{{option}} </div>
For horizontal alignment, this worked. Instead of repeating div, I repeated label. label wraps the input so option is in scope of input - <div > <label *ngFor = "let option of this.selectOptions; let ind=index"> <input type="radio" [id]="option" name="children" [value]=option [(ngModel)]="this.children"> {{option}} </label> </div>

Styling Data Validation Errors with Bootstrap

I am working on an ASP.NET MVC 4 Project. I want to style data validation errors on my login page with Bootstrap 3.0. When I debug the page and it gives data validation errors, this codes are disappeared in source of my login form:
<form action="/Account/Login" class="col-md-4 col-md-offset-4 form-horizontal well" method="post"><input name="__RequestVerificationToken" type="hidden" value="Zbg4kEVwyQf87IWj_L4alhiHBIpoWRCJ9mRWXF6syGH4ehg9idjJCqRrQTMGjONnywMGJhMFmGCQWWvBbMdmGFSUPqXpx6XaS4YfpnbFm8U1" /><div class="validation-summary-errors"><ul><li>The user name or password provided is incorrect.</li>
</ul></div> <div class="form-group control-group">
<div class="col-md-6 col-md-offset-3">
<input class="input-validation-error form-control" data-val="true" data-val-required="User name alanı gereklidir." id="UserName" name="UserName" placeholder="Kullanıcı Adı" type="text" value="" />
<span class="field-validation-error" data-valmsg-for="UserName" data-valmsg-replace="true">User name alanı gereklidir.</span>
</div>
</div>
<div class="form-group">
<div class="col-md-6 col-md-offset-3">
<input class="input-validation-error form-control" data-val="true" data-val-required="Password alanı gereklidir." id="Password" name="Password" placeholder="Şifre" type="password" />
<span class="field-validation-error" data-valmsg-for="Password" data-valmsg-replace="true">Password alanı gereklidir.</span>
</div>
</div>
<div class="form-group">
<div class="col-md-4 col-md-offset-4">
<button class="btn btn-default" type="submit">Giriş Yap</button>
</div>
</div>
</form>
How can I style these errors like "for=inputError" property of label with Bootstrap 3?
As it's shown in Bootstrap's docs, you need to apply class has-error to the div that contains the input and has class form-group:
<div class="form-group has-error">
...
</div>
It's a quite ugly to write a condition for each property you want to check and apply class has-error depending on the results of that condition, though you can do it like so:
<div class="form-group #(Html.ViewData.ModelState.IsValidField(Html.IdFor(x => x.UserName)) ? null : "has-error" )">
This takes care of the server side validation. However, there is also client side validation you need to think about. For that you'd need to write some jQuery that would check for existence of class field-validation-error and apply class has-error depending on the result.
You may do it all your self, though I suggest checking out TwitterBootstrapMVC which does all of that automatically for you. All you'd have to write is:
#Html.Bootstrap().FormGroup().TextBoxFor(m => m.UserName)
Disclaimer: I'm the author of TwitterBootstrapMVC. Using it in Bootstrap 2 is free. For Bootstrap 3 it requires a paid license.

Struts 1 Nested tags: getting unexpected html

I am working on an old application using Struts 1. We are using nested tags. For below code:
<nested:form action="/save.do?method=save">
<h2>Indexed Property Example</h2>
<nested:iterate property="lines" indexId="idx">
Name: <nested:text property="name" indexed="true"/>
Town: <nested:text property="town" indexed="true"/>
<nested:iterate property="inches" indexId="j">
Inch: <nested:text property="length" indexed="true"></nested:text>
</nested:iterate>
</nested:iterate>
<nested:submit value="save" />
</nested:form>
I am getting below html:
<h2>Indexed Property Example</h2>
Name: <input name="nestedForm[0].lines[0].name" value="" type="text">
Town: <input name="nestedForm[0].lines[0].town" value="" type="text">
Inch: <input name="nestedForm[0].lines[0].inches[0].length" value="0" type="text">
Inch: <input name="nestedForm[1].lines[0].inches[1].length" value="0" type="text">
<input name="" value="save" type="submit">
If you see in second Inch label we have nestedForm[1] it should be 0. I have to change to this data and submit back to server. If I change it directly in html struts populate all objects automatically. Can anyone suggest me if I am doing anything wrong here.