In my app I have selectOneMenu to select month.
<h:selectOneMenu value="#{register.monthOfBirth}">
<f:selectItems value="#{register.dateValues.monthsList}" var="month" itemLabel="#{month.valueLabel}" itemValue="#{month.valueValue}"/>
<f:ajax listener="#{register.monthChanged}" render="messages" />
</h:selectOneMenu>
Here's my DateValues class which I use to populate selectOneMenu's:
public class DateValues {
public static class Values{
public String valueLabel;
public String valueValue;
public Values(String valueLabel, String valueValue){
this.valueLabel = valueValue;
this.valueLabel = valueValue;
}
public String getValueLabel(){
return valueLabel;
}
public String getValueValue(){
return valueValue;
}
}
public Values[] daysList;
public Values[] monthsList;
public Values[] yearsList;
public DateValues(){
daysList = new Values[31];
for(int i=0;i<31;i++){
daysList[i] = new Values(""+ (i+1),""+(i+1));
}
monthsList = new Values[12];
for(int i=0;i<12;i++){
monthsList[i] = new Values("" + (i+1),"" + (i+1));
}
yearsList = new Values[109];
Calendar cal = Calendar.getInstance();
int currentYear = cal.get(Calendar.YEAR);
int first = currentYear - 108;
for(int i=0;i<109;i++) {
yearsList[i] = new Values("" + (first + (108-i)),"" + (first + (108-i)));
}
}
public Values[] getDaysList() {
return daysList;
}
public Values[] getMonthsList() {
return monthsList;
}
public Values[] getYearsList() {
return yearsList;
}
}
In the #ManagedBean I've got an ajax listener:
public void monthChanged(){
System.out.println("New month is month number " + monthOfBirth);
}
What I get in the output is:
"INFO: New month is month number dyplom.dyplom.date.DateValues$Values#79f6099"
instead of (for example) 2 (number of month, so February)
What did I do wrong?
EDIT:
GENERATED HTML:
<h2><select id="j_idt56:j_idt70" name="j_idt56:j_idt70" size="1" onchange="mojarra.ab(this,event,'valueChange',0,'j_idt56:messages')"> <option value="dyplom.dyplom.date.DateValues$Values#32b0c37e">1</option>
<option value="dyplom.dyplom.date.DateValues$Values#72f29f31">2</option>
<option value="dyplom.dyplom.date.DateValues$Values#16b184ec">3</option>
<option value="dyplom.dyplom.date.DateValues$Values#608dad97">4</option>
<option value="dyplom.dyplom.date.DateValues$Values#757fc606">5</option>
<option value="dyplom.dyplom.date.DateValues$Values#17a1f02e">6</option>
<option value="dyplom.dyplom.date.DateValues$Values#89f6821">7</option>
<option value="dyplom.dyplom.date.DateValues$Values#196d52f3">8</option>
<option value="dyplom.dyplom.date.DateValues$Values#5860dc8f">9</option>
<option value="dyplom.dyplom.date.DateValues$Values#3f305d9d">10</option>
<option value="dyplom.dyplom.date.DateValues$Values#520ed4">11</option>
<option value="dyplom.dyplom.date.DateValues$Values#b4b8076">12</option>
</select>
</h2>
Problem solved!
I'm so ashamed of the mistake I made!
Take a look at the constructor of Values:
public Values(String valueLabel, String valueValue){
this.valueLabel = valueValue;
this.valueLabel = valueValue;
}
As you can see I've been setting up twice valueLabel with wrong variable and moreover I didn't set valueValue at all!
Now as I corrected constructor:
public Values(String valueLabel, String valueValue){
this.valueLabel = valueLabel;
this.valueValue = valueValue;
}
everything is alright :)
Sorry for the mess!
Related
I have configured a simple member login and the search return value is null
In DAO, the return value of selectOne in sqlSession is null.
insert statement works fine
can i know the solution?
loginPage.html
<form action="/memberLogin" method="post" class="login100-form validate-form">
<div class="wrap-input100 validate-input m-b-26" data-validate="Username is required">
<span class="label-input100">Username</span>
<input class="input100" type="text" name="member_name" placeholder="Enter username">
<span class="focus-input100"></span>
</div>
<div class="wrap-input100 validate-input m-b-18" data-validate = "Password is required">
<span class="label-input100">Password</span>
<input class="input100" type="password" name="member_pwd" placeholder="Enter password">
<span class="focus-input100"></span>
</div>
<div class="flex-sb-m w-full p-b-30">
<div class="contact100-form-checkbox">
<input class="input-checkbox100" id="ckb1" type="checkbox" name="remember-me">
<label class="label-checkbox100" for="ckb1">
Remember me
</label>
</div>
<div>
<a href="#" class="txt1">
Forgot Password?
</a>
</div>
</div>
<div class="container-login100-form-btn">
<button type="submit" class="login100-form-btn">
login
</button>
<button type="button" id = "loginBtn" class="login100-form-btn"><a href="/signUp">
signUp</a>
</button>
</div>
</form>
MemberController
#PostMapping(value = "/memberLogin")
public String login(MemberDTO memberDTO, HttpServletRequest request) throws Exception {
HttpSession session = request.getSession();
session.setMaxInactiveInterval(3600);
System.out.println("세션 아이디 : " + session.getId());
System.out.println("세션 유효시간 : " + session.getMaxInactiveInterval());
System.out.println("memberDTO : " + memberDTO);
MemberDTO member = memberService.login(memberDTO);
System.out.println("member : " + member);
if (member != null){
session.setAttribute("member", member);
System.out.println("로그인 성공");
return "redirect:/";
} else {
System.out.println("로그인 실패");
return "redirect:login";
}
}
MemberService
#Override
public MemberDTO login(MemberDTO memberDTO) throws Exception {
System.out.println("login Service : " + memberDTO);
return memberDAO.login(memberDTO);
}
MemberDAO
#Override
public MemberDTO login(MemberDTO memberDTO) throws Exception {
MemberDTO member = null;
System.out.println("DAO : " + memberDTO);
member = sqlSession.selectOne(NAMESPACE + "loginCheck", memberDTO);
System.out.println("dao : " + member);
return sqlSession.selectOne(NAMESPACE + "loginCheck", memberDTO);
}
MemberDTO
public class MemberDTO {
private String member_name;
private String member_pwd;
private String member_email;
private String member_role;
private Date member_register_datetime;
public String getMember_name() {
return member_name;
}
public void setMember_name(String member_name) {
this.member_name = member_name;
}
public String getMember_pwd() {
return member_pwd;
}
public void setMember_pwd(String member_pwd) {
this.member_pwd = member_pwd;
}
public String getMember_email() {
return member_email;
}
public void setMember_email(String member_email) {
this.member_email = member_email;
}
public String getMember_role() {
return member_role;
}
public void setMember_role(String member_role) {
this.member_role = member_role;
}
public Date getMember_register_datetime() {
return member_register_datetime;
}
public void setMember_register_datetime(Date member_register_datetime) {
this.member_register_datetime = member_register_datetime;
}
#Override
public String toString() {
return "MemberDTO{" +
"member_name='" + member_name + '\'' +
", member_pwd='" + member_pwd + '\'' +
", member_email='" + member_email + '\'' +
", member_role='" + member_role + '\'' +
", member_register_datetime=" + member_register_datetime +
'}';
}
}
MemberMapper.xml
<mapper namespace="member">
<insert id = "signUp" parameterType="com.withstudy.domain.MemberDTO">
insert into MEMBER
values (#{member_email, jdbcType = VARCHAR}, #{member_pwd, jdbcType = VARCHAR}, #{member_name, jdbcType = VARCHAR}, 'General', sysdate)
</insert>
<select id = "loginCheck" parameterType="com.withstudy.domain.MemberDTO" resultType="com.withstudy.domain.MemberDTO">
SELECT * FROM MEMBER
WHERE MEMBER_NAME = #{member_name, jdbcType = VARCHAR}
AND MEMBER_PWD = #{member_pwd, jdbcType = VARCHAR}
</select>
</mapper>
Oracle DB(SQL Developer)
enter image description here
Console
enter image description here
It is a good practice to list columns that you are expected to map on your Entity in SELECT statement. You can accidentally pull something big and query performance may degradates. So try to list them first:
SELECT
member_name,
member_pwd,
member_email,
member_role,
member_register_datetime;
FROM MEMBER
WHERE MEMBER_NAME = #{member_name, jdbcType = VARCHAR}
AND MEMBER_PWD = #{member_pwd, jdbcType = VARCHAR}
My requirement is I have 4 textboxes rendered using a for loop on model, when I entered a value and focus out of any text box, I need to capture the value into a variable and show it in a span before submit
I have tried with call a function in blur event
<EditForm EditContext="#EditContext">
<DataAnnotationsValidator />
#for (int j = 0; j < transactionModels.Count; j++)
{
int i = j;
<input type="text" class="form-control"
#bind="transactionModels[i].Amount" #onblur="Getvalue" placeholder="Amount" />
<span>**Textboxvalue** </span>
}
</EditForm>
#code{
public void Getvalue()
{
Textboxvalue= transactionModels.Amount
}
The code below is a demo page showing how to link an array of values into a set of text boxes and have the array update. You should be able to adapt it to your specific circumstances. (I made an assumption that amount is a number, not text).
#page "/"
<h2>Home Page</h2>
<EditForm EditContext="this.editContext">
#foreach (var modelData in _model.data)
{
<div>
<InputNumber #bind-Value="modelData.Amount"></InputNumber>
</div>
<div>
Value: #modelData.Amount
</div>
}
</EditForm>
#code {
public class ModelData
{
public int Amount { get; set; }
}
public class Model
{
public List<ModelData> data = new List<ModelData> {
new ModelData { Amount = 12},
new ModelData { Amount = 10},
new ModelData { Amount = 8},
new ModelData { Amount = 6},
};
}
private EditContext editContext;
protected Model _model { get; set; } = new Model();
protected override Task OnInitializedAsync()
{
editContext = new EditContext(_model);
return base.OnInitializedAsync();
}
}
Stick with #foreach for these situations. If you use #for you need to define a local variable for each loop.
I don't think you really need to use "onblur", which is javascript-minded, not Blazor.
Replace your <input type="text"... by
<InputText type="text" class="form-control" #bind-Value="transactionModels[i].Amount" placeholder="Amount" />
The span should become
<span>#transactionModels[i].Amount </span>
If transactionModels[i].Amount is of numeric type (what is suggested by the name, but not your choice of type="text"), replace <InputText type="text" by <InputNumber.
If it is a string, do not forget to remove special characters to prevent XSS.
Edit after 2nd comment:
In the transactionModel class, add these properties
private double amount;
internal double Amount
{
get => amount;
set
{
LoanRelatedPopupVisible = (value < 0);
DepositRelatedPopup = (value > 0);
amount = value;
}
}
internal bool LoanRelatedPopupVisible { get; set; }
internal bool DepositRelatedPopup { get; set; }
To manage the visibility of the popup
#if (transactionModels[i].LoanRelatedPopupVisible)
{
<div here the popup ...
}
I am not an expert MVC programmer but have to make a small change in the code. Any help?
I have a field CallerType which had [required] attribute. However, I do not want to be mandatory anymore so I am removing [required] attribute but still get the same input required error.
public virtual CallType CallType { get; set; }
[Display(Name = "Type of Calls")]
/*Akbar-start*[Required]*Akbar-end*/
public int CallTypeID { get; set; }
<div class="form-group col-3">
<label asp-for="Intake.CallTypeID" class="control-label"></label>
<select asp-for="Intake.CallTypeID"class="form-control">asp-items="Model.CallTypes">
<option value="">Please Select</option>
</select>
<span asp-validation-for="Intake.CallTypeID" class="text-danger"></span>
</div>
Error:
enter image description here
I also see javascript like below but not sure how this is getting invoked:
$('input').each(function () {
var req = $(this).attr('data-val-required');
var hide = $(this).attr('hide-required-indicator');
var hasIndicator = $(this).hasClass('has-required-indicator');
if (undefined != req && undefined == hide && !hasIndicator) {
var label = $('label[for="' + $(this).attr('id') + '"]');
var text = label.text();
if (text.length > 0) {
label.append('<span style="color:red" class="required-indicator"> *</span>');
$(this).addClass('has-required-indicator');
}
}
});
$('select').each(function () {
var req = $(this).attr('data-val-required');
var hasIndicator = $(this).hasClass('has-required-indicator');
if (undefined != req && !hasIndicator) {
var label = $('label[for="' + $(this).attr('id') + '"]');
var text = label.text();
if (text.length > 0) {
label.append('<span style="color:red"> *</span>');
$(this).addClass('has-required-indicator');
}
}
});
I was able to solve this issue.
Here is the trick:
Changed int to int?
public int CallTypeID { get; set; }
i.e.
public int? CallTypeID { get; set; }
? indicates that this field is nullable. It was overriding [Required] attribute
Hi I am quite new on MVC and I am trying to create a simple conversion from Fahrenheit to Celsius along with its unit testing. Sorry in advance for putting all the code here.
This is my controller code:
public string Convert(double value,string option)
{
string d;
if(option=="1") {
d = " To Celcius"+FahrenheitToCelsius(value).ToString();
}
else {
d = " To Fahrenheit" + CelsiusToFahrenheit(value).ToString();
}
return "ConvertTo" + d;
}
public static double CelsiusToFahrenheit(double temperatureCelsius)
{
double celsius = temperatureCelsius;
return (celsius * 9 / 5) + 32;
}
public static double FahrenheitToCelsius (double temperatureFahrenheit)
{
double fahrenheit = temperatureFahrenheit;
return (fahrenheit - 32) * 5 / 9;
}
This is my View Page
protected void btnConvert(object sender, EventArgs e)
{
if (DropDownList1.SelectedValue=="1"){
double temp = TemperatureConverterController.FahrenheitToCelsius(double.Parse(TextBox1.Text));
Literal1.Text = temp.ToString();
}
else{
double temp = TemperatureConverterController.CelsiusToFahrenheit(double.Parse(TextBox1.Text));
Literal1.Text = temp.ToString();
Literal1.Text = temp.ToString();
}
}
When i do this unit testing i got an error:
[TestMethod]
public void ConvertReturnsAViewResultWhenInputDataIsValid()
{
//Arrange
var controller = new TemperatureConverterController();
//Act
double x = 80;
double y = 25;
var result = controller.Convert(x, "1") as ViewResult;
// here i get this error under ViewResult //
//Assert
Assert.IsInstanceOfType(result, typeof(ViewResult));
}
[TestMethod]
public void ConvertAsksForAViewTemplateNamedConvert()
{
//Arrange
var controller = new TemperatureConverterController();
String expectedViewTemplate = "Convert";
//Act
double x = 80;
double y = 25;
var result = controller.Convert(x, "1") as ViewResult;
////Assert
Assert.AreEqual<String>(expectedViewTemplate, result.ViewName);
}
Error is:
Error Cannot convert type 'string' to 'System.Web.Mvc.ViewResult' via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion.
the problem is here
var result = controller.Convert(x, "1") as ViewResult;
your Convert method is returning string and you are casting it as ViewResult
Your convert method should looks like
public ActionResult Convert()
{
//Make a Model class and pass it to View
//...
return View(model_class_object);
}
Alternatively you can make controller like this
public ActionResult Convert()
{
ViewData["tempvalue"]=Convert(x, "1");
//Make a Model class and pass it to View
//...
return View();
}
and on your View you can just print it
#ViewData["tempvalue"].ToString()
In MVC the controller code should return an "ActionResult" object containing the model.
If the data you want to pass to view is simply a string use:
public ActionResult Convert()
{
//...
return View("your result here...");
}
You can refer to data returned by controller using the "Model" property in Views or Tests.
Let's go backwards for a minute here.
Controller
public class ConvertController : Controller
{
public ActionResult Convert(MyConvertViewModel vm)
{
if (vm == null) { return View("convert", new MyConvertViewModel { ShowResult = false }); }
if (vm.Option == 1)
{
vm.Result = FahrenheitToCelsius(vm.Input);
vm.OptionName = "Fahrenheit To Celsius";
}
else
{
vm.Result = CelsiusToFahrenheit(vm.Input);
vm.OptionName = "Celsius to Fahrenheit";
}
vm.ShowResult = true;
//not needed, just for an example
ViewData.Add("glosrob-example", "A value goes here!");
return View("convert", vm);
}
private static double CelsiusToFahrenheit(double temperatureCelsius)
{
double celsius = temperatureCelsius;
return (celsius * 9 / 5) + 32;
}
private static double FahrenheitToCelsius(double temperatureFahrenheit)
{
double fahrenheit = temperatureFahrenheit;
return (fahrenheit - 32)*5/9;
}
}
public class MyConvertViewModel
{
public double Result { get; set; }
public int Option { get; set; }
public double Input { get; set; }
public string OptionName { get; set; }
public bool ShowResult { get; set; }
}
View
#model MvcApplication1.Controllers.MyConvertViewModel
#{
ViewBag.Title = "Convert";
}
<h2>Convert</h2>
#using (Html.BeginForm("convert", "convert", FormMethod.Post))
{
<div>
Let's convert some temperatures!
</div>
<div>
#Html.LabelFor(x => x.Input, "Temp. To Convert")
#Html.TextBoxFor(x => x.Input)
</div>
<div>
#Html.LabelFor(x => x.Option, "Convert to ")
#Html.DropDownListFor(x => x.Option, new List<SelectListItem>
{
new SelectListItem {Text = "Celsius", Value = "1"},
new SelectListItem {Text = "Fahrenheit", Value = "2"}
})
</div>
<div>
<button type="submit">Convert It!</button>
</div>
}
#if (Model.ShowResult)
{
<p>#Model.OptionName : #Model.Input = #Model.Result</p>
}
disclaimer: there is a lot of shortcuts there, it is only included to give you an idea of what you should have.
So the view will post back data the user chooses, to the controller action Convert
The controller in turn will return a ViewResult object, and it will be rendered using the data captured in the view model MyConvertViewModel
Now we want to test this.
So here are some of the more important properties that it seems like you need to hook into
[TestMethod]
public void Not_A_Real_Test_But_Stuff_You_Will_Want_To_Use()
{
//arrange
var c = new ConvertController();
//act
var results = c.Convert(null) as ViewResult;
//now results is a ViewResult or null
var theViewModelProperty = results.Model as MyConvertViewModel;
var exampleResult = theViewModelProperty.Result;
var exampleInput = theViewModelProperty.Input;
//etc
//how about the view that was returned?
var theViewName = results.ViewName;
//or anything you put in the ViewData
var theViewData = results.ViewData["glosrob-example"];
Assert.Fail("This was not a real test!");
}
Hopefully this gives you an idea of how you can test for output from a controller method.
Edit: I'm not writing all your tests for you but as an e.g.
[TestMethod]
public void Convert_Should_Return_A_MyConvertViewModel()
{
//arrange
var c = new Controller();
//act
var result = c.Convert(null) as ViewResult;
//assert
Assert.IsNotNull(result);
Assert.IsInstanceOfType(result.ViewModel, typeof(MyConvertViewModel));
}
[TestMethod]
public void Convert_Should_Return_The_Correct_View()
{
//arrange
var c = new Controller();
//act
var result = c.Convert(null) as ViewResult;
//assert
Assert.IsNotNull(result);
Assert.AreEqual("convert", result.ViewName);
}
I have a main view using a ViewModel. Inside the ViewModel I do this (Edited to show complete ViewModel):
namespace MyNameSpace.ViewModels
{
public class MyViewModel
{
public ModelOne ModelOne { get; set; }
public ModelTwo ModelTwo { get; set; }
}
}
On my main view I do this (EDIT: Added #Html.Hidden code):
#using MyNameSpace.ViewModels
#using MyNameSpace.Models
#model MyViewModel
...
#using (Html.BeginFormAntiForgeryPost())
{
#Html.Hidden("myData", new MvcSerializer()
.Serialize(Model, SerializationMode.Signed))
....
<div>
#{Html.RenderPartial("_MyCheckBox",
Model.ModelTwo, new ViewDataDictionary());}
</div>
}
....
My partial view is:
#using MyNameSpace.Models
#model ModelTwo
<div>
<fieldset>
<div class="editor-label">
#Html.LabelFor(x => x.MyCheckBox)</div>
<div class="editor-field">
<select multiple="multiple" id="#Html.FieldIdFor(x =>
x.MyCheckBox)" name="#Html.FieldNameFor(x =>
x.MyCheckBox)">
#foreach (MyEnum item in Enum.GetValues(typeof(MyEnum)))
{
var selected = Model.MyCheckBox.Contains(item); //ERROR HERE
<option value="#((int)item)" #if (selected)
{<text>selected="selected"</text>}>
#T(item.ToString())
</option>
}
</select>
</div>
</fieldset>
</div>
I am getting the Object reference not set to an instance ... error and am not sure how to correct it.
Originally, I had that <fieldset> inside my main view and was getting that error. I thought it was because of the two models and that's why I placed it in a partial view. But only to discover I am running into the same problem.
I am not setting the MyCheckBox in my partial view on the line var selected = Model.MyCheckBox.Contains(item); properly.
Any thoughts?
EDIT (Adding MyCheckBox code)
Here is MyCheckBox inside ModelOne.cs:
[Mandatory(ErrorMessage = "Please select at least one option")]
[Display(Name = "Please select one ore more options")]
[MySelector]
public virtual int MyCheckBox { get; set; }
And here it is inside ModelTwo.cs:
private IList<MyEnum> _myEnum;
public IList<MyEnum> MyCheckBox
{
get
{
if (_myEnum== null)
{
_myEnum= new List<MyEnum>();
foreach (MyEnumitem in Enum.GetValues(typeof(MyEnum)))
{
if (((MyEnum)Record.MyCheckBox& item) == item)
_myEnum.Add(item);
}
}
return _myEnum;
}
set
{
_myEnum= value;
Record.MyCheckBox= 0;
foreach (var item in value)
{
Record.MyCheckBox|= (int)item;
}
}
}
Please note, I am using Orchard (hence the Record) which, in turn, uses NHibernate. I don't believe that is relevant, but I could be wrong. The MyCheckBox code is using [Flags] attribute of enum and storing the value as an int in the DB (hence the proxy). Here is what the enum would look like:
MyEnum.cs:
[Flags]
public enum MyEnum
{
[Display(Name="Name 1")]
Enum1 = 1,
[Display(Name="Name 2")]
Enum2 = 2,
[Display(Name="Name 3")]
Enum3 = 4,
[Display(Name="Name 4")]
Enum4 = 8,
[Display(Name="Name 5")]
Enum5 = 16
}
MyController.cs
private MyViewModel myData;
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
var serialized = Request.Form["myData"];
if (serialized != null) //Form was posted containing serialized data
{
myData= (MyViewModel)new MvcSerializer().Deserialize
(serialized, SerializationMode.Signed);
TryUpdateModel(myData);
}
else
myData= (MyViewModel)TempData["myData"] ?? new MyViewModel();
TempData.Keep();
}
protected override void OnResultExecuted(ResultExecutedContext filterContext)
{
if (filterContext.Result is RedirectToRouteResult)
TempData["myData"] = myData;
}
Then in the particular Action within *MyController.cs:
public ActionResult Step5(string backButton, string nextButton)
{
if (backButton != null)
return RedirectToAction("Step4");
else if ((nextButton != null) && ModelState.IsValid)
return RedirectToAction("Confirm");
else
return View(myData);
}