The issue with cascading dropdown lists using ajax and HDIV - spring-mvc

I integrated HDIV and Spring MVC. Now I have a form on which there are three dropdown lists contract, taskorder and subtask. The select change of contract will update the content of taskorder dropdown list via ajax and then the select change of the task order will update the content of dropdown list subtask via ajax. The form looks like this:
<c:url var="url" value="/admin/user/newstafftask" >
<c:param name="_MODIFY_HDIV_STATE_" value="${taskOrder.id}" />
</c:url>
<form:form action="${url}" commandName="newRequestStaffTasks">
<form:hidden path="subId" />
<table >
<tr>
<td> <label>Contract </label></td>
<td>
<form:select path="newRequestStaffContract.id">
<option></option>
<form:options items="${contractList}" itemValue="id" itemLabel="contract.contractNbr" />
</form:select>
</td>
</tr>
<tr>
<td> <label>Task Order </label></td>
<td>
<form:select path="taskOrder.id">
</form:select>
</td>
</tr>
<tr>
<td> <label>SubTask Code </label></td>
<td>
<form:select path="subtask.subTaskId">
<option></option>
</form:select>
</td>
</tr>
</table>
</form:form>
When I tried to submit the form, I got the error message "INVALID_PARAMETER_NAME" about the taskOrder.id. I understand the problem is the values of two dropdown lists were updated on the client side.I tried _MODIFY_HDIV_STATE_, but it did not work with this case. So I am not sure how to deal with it now. Please help. Thanks.
Update 1
I already exclude the Ajax request from the HDIV validation. Below is the code snippet that update taskOrder list when the contract select change:
$(".modal-body").on("change", "#newRequestStaffContract\\.id", function() {
getTaskOrderByContract($(this));
});
function getTaskOrderByContract(o) {
contractId = o.val();
if (contractId) {
$.get("../../ajax/getTaskOrderByContract", {
contractId : contractId
}
, function(data) {
var options = '<option value=""></option>';
for (var i = 0; i < data.length; i++) {
options += '<option value="' + data[i].id + '">' +data[i].taskNum+ '</option>';
}
$('#taskOrder\\.id').html(options);
});
};
};

Related

How to display properties of specific object selected via dropdown?

I wrote a query in which I get the semester class, display its values ​​as a name and get its id. Accordingly, when I select the semester I need in the drop-down list, I am given the semester that I chose. But I also need to display its duration in another field, I can do this if I create a ForEach loop and use it to extract this value, but it displays absolutely all the available values, and not the one I need. Tell me how to do it right? For display I use Spring MVC. Now the page looks like this:
I am also attaching the jsp content:
<form:form action="allSemestrsSem" method="get" id="selectSemestr" modelAttribute="semestr">
<tr>
<td style="font-size: large;">Select semester</td>
<td style="padding-left: 50px">
<select name="selectSemestr">
<c:forEach items="${semestr}" var="semestr">
<option value="${semestr.id}">${semestr.name}</option>
</c:forEach>
</select>
</td>
<td style="padding-left: 20px">
<security:authorize access="hasRole('ADMIN')">
<input type="submit" id="button" value="select" /></td>
</security:authorize>
</tr>
<tr height="80px" style="font-size: large; font-weight: bold;">
<td colspan="3">Semester duration:
<c:forEach items="${semestr}" var="semestr"> ${semestr.duration} </c:forEach>
</td>
</tr>
</form:form>
And just in case my controller is:
#RequestMapping(value = "/allSemestrsSem", method = RequestMethod.GET)
public String allSemestrs(#RequestParam(name = "selectSemestr") String selectSemestr, Model model) {
List<Semestr> semestr = service.getSemestr();
model.addAttribute("semestr", semestr);
List<Discipline> allDisciplines = service.getDisciplineSemestrId(Integer.valueOf(selectSemestr));
model.addAttribute("allDisc", allDisciplines);
return "semestr";
}

Checkbox not being rendered with correct gentelella css when added via javascript

I'm trying to add some rows data in a datatable, first via Pug and then later on via javascript.
I add the first rows getting data via controller call, and then adding it via pug parse:
<div class="x_content">
<table id="datatable-buttons" class="table table-striped table-bordered bulk_action">
<thead>
<tr>
<th>
<th>Aprovado</th>
</th>
<th>Nome</th>
<th>Email</th>
<th>Data de nascimento</th>
<th>Cidade</th>
<th>Gênero</th>
<th>Escolaridade</th>
<th>Instituição de ensino</th>
<th>Semestre</th>
<th>Token</th>
<th>Selection Status</th>
</tr>
</thead>
<tbody>
for candidate in candidates
- var formatedCandidate = candidateService.formatCandidateForDataTable(candidate, newTrueCheckbox, newFalseCheckbox);
<tr>
<td>
<th>
if formatedCandidate.isCandidateApproved
<input type="checkbox" id="check-all" class="flat" checked>
else
<input type="checkbox" id="check-all" class="flat">
</th>
</td>
<td>
= formatedCandidate.name
</td>
<td>
= formatedCandidate.email
</td>
<td>
= formatedCandidate.bornDate
</td>
<td>
= formatedCandidate.city
</td>
<td>
= formatedCandidate.gender
</td>
<td>
= formatedCandidate.educationLevel
</td>
<td>
= formatedCandidate.educationInstitution
</td>
<td>
= formatedCandidate.educationSemester
</td>
<td>
= formatedCandidate.token
</td>
<td>
= formatedCandidate.selectionStatus
</td>
</tr>
</tbody>
</table>
This way, it manages to render the checkbox with the right style:
Later on, I try to update the rows via a "reload" button, getting data via a get request and then adding rows via javascript:
$.get("candidates/getCandidatesForTable", function(candidatesArray){
candidateTable.clear().draw();
candidatesArray.forEach((candidate, index) => {
debugger;
if (candidate[1]) {
candidate[1] = `<th>
<input type="checkbox" id="check-all" class="flat" checked/>
</th>`;
} else {
candidate[1] = `<th>
<input type="checkbox" id="check-all" class="flat"/>
</th>`;
}
candidateTable.row.add(candidate).draw();
});
});
Although I inserted the HTML code via javascript using the same properties as it was added via pug, the checkbox was rendered different: it is rendered, but the css style is now gone:
How should I add the a checkbox via javascript and still get the correct css styling?

InitBinder on multiple form objects

Can you have a #Initbinder on several data in the same form?
I have a spring form which contains a select dropdown of an object and two datafields, I have an Initbinder on the dates otherwise I get an error on submit. But I also need to bind the dropdown to an object.
I have a Type which has two dates and a Category, and it is the Category I need to bind because it can not be empty on save.
I think it will help me to validate the form to.
So can I have this in my Type controller?
#InitBinder
public void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
binder.registerCustomEditor(Category.class, "category", new CategoryEditor(CategoryService));
}
And this is the Editor:
public class CategoryEditor extends PropertyEditorSupport {
private CategoryService categoryService;
public CategoryEditor(CategoryService categoryService) {
this.categoryService = categoryService;
}
#Override
public void setAsText(String text) throws IllegalArgumentException {
if (text.equals("0")) {
this.setValue(null);
} else {
Category sc = categoryService.getCategory(Integer.parseInt(text));
this.setValue(sc);
}
}
#Override
public String getAsText() {
Category parent = new Category();
if (this.getValue() != null) {
parent = (Category) this.getValue();
}
return "";
}
}
And my jsp-page
<s:url value="/mvc/type/save" var="actionUrl" />
<sf:form method="POST" modelAttribute="type" action="${actionUrl}">
<fieldset>
<legend><s:message code="${heading}" /></legend>
<table>
<tr>
<th><label for="category"><s:message code="category" />:</label></th>
<td><sf:select path="category.ID" id="category">
<sf:option value="0"> </sf:option>
<sf:options items="${listOfCategories}" itemLabel="name" itemValue="ID" />
</sf:select></td>
</tr>
<tr>
<th><label for="name"><s:message code="name" />:</label></th>
<td><sf:input path="name" id="name" />
<sf:hidden path="ID" />
<sf:hidden path="version" /></td>
</tr>
<tr>
<th><label for="marketing"><s:message code="marketing" />:</label></th>
<td><sf:input path="marketingFunction" id="marketing" /></td>
</tr>
<tr>
<th><label for="status"><s:message code="status" />:</label></th>
<td><sf:select path="lifeCycleStatus">
<sf:option value="0"> </sf:option>
<sf:options items="${listOfEnums}" />
</sf:select></td>
</tr>
<tr>
<th><label for="validfrom"><s:message code="validfrom" />:</label></th>
<td><sf:input path="validFrom" id="validfrom" /></td>
</tr>
<tr>
<th><label for="validuntil"><s:message code="validuntil" />:</label></th>
<td><sf:input path="validUntil" d="validuntil" /></td>
</tr>
<tr>
<td colspan="2">
<input id="saveButton" class="right" type="submit" title="<s:message code="save" />" value=" [ <s:message code="save" /> ] " />
</td>
</tr>
</table>
</fieldset>
</sf:form>
So my question: Can I have multiple binder in the same initBinder in my controller? It seems like I can't because I never enter the CategoryEditor. How do I do this?
There aren't multiple binders, there are multiple PropertyEditors.
Your custom one is never called because you are binding the wrong path.
<sf:select path="category.ID" id="category">
You must bind to category and not category.ID
<sf:select path="category" id="category">

store string and grab with JSON

<script>
function ShowCommentBox() {
$("#dialog").dialog({ modal: true });
}
function GrabDetails() {
var obj = jQuery.parseJSON('{"name":"John"}');
$("#item").val(obj.name);
}
</script>
<div id="dialog" title="Comments" style="display:none;">
<table class="detailstable FadeOutOnEdit">
<tr>
<th>Item</th>
</tr>
<tr>
<td><asp:Label ID="ItemIdLabel" Text="item" runat="server"/></td>
</tr>
</table>
</div>
<input id="SubmitCommentsToInvoice" type="button" value="Comments" onclick="ShowCommentBox()" />
In my asp.net project when the user clicks the 'Comments' button the div appears containing the label.
I'm trying to use JSON to display the string "John" - stored in them #item object in the 'GrabDetails()'
Then in the label text="" How do I pull across the value stored in the #item object.
Thanks
#item is an ID selector in jQuery, which there is no element here with ID "item". Also, <asp:Label /> renders from the server as html in a different way. However, it appears you are not using this label on the server side at all? if this is the case i would just make an html element like
<td id="WhereNameGoes"></td>
then
function GrabDetails() {
var obj = jQuery.parseJSON('{"name":"John"}');
$("#WhereNameGoes").text(obj.name);
// this still needs to be called somewhere, perhaps in ShowCommentBox()?
}
jQuery $.val() is more for <input /> elements

ASP.net looping through table

I was wondering if any one could help me out; I have a table which looks something like the following:
<table id="Table1" border="0">
<tr>
<td><b>1.</b> Question 1</td>
</tr><tr>
<td style="border-width:5px;border-style:solid;"></td>
</tr><tr>
<td align="left" style="width:1000px;"><input id="Radio1" type="radio" name="Group1" value="Radio1" /><label for="Radio1">Answer1</label></td>
</tr><tr>
<td align="left" style="width:1000px;"><input id="Radio1" type="radio" name="Group1" value="Radio1" /><label for="Radio1">Answer2</label></td>
</tr><tr>
<td align="left" style="width:1000px;"><input id="Radio1" type="radio" name="Group1" value="Radio1" /><label for="Radio1">Answer3</label></td>
</tr><tr>
<td align="left" style="width:1000px;"><input id="Radio1" type="radio" name="Group1" value="Radio1" /><label for="Radio1">Answer4</label></td>
</tr><tr>
<td style="height:30px;"></td>
</tr><tr>
<td><b>2.</b> Question 2</td>
</tr><tr>
<td style="border-width:5px;border-style:solid;"></td>
</tr><tr>
<td align="left" style="width:1000px;"><input id="Radio2" type="radio" name="Group2" value="Radio2" /><label for="Radio2">yes</label></td>
</tr><tr>
<td align="left" style="width:1000px;"><input id="Radio2" type="radio" name="Group2" value="Radio2" /><label for="Radio2">no</label></td>
</tr><tr>
<td style="height:30px;"></td>
</tr>
</table>
How do I go about looping through each group of radio buttons and getting the text of the selected radio button?
The code displayed above is created dynamically ... in my aspx file I have the following code:
<asp:Table ID="Table1" runat="server">
</asp:Table>
If you want to access the rows in ASP.NET (on the server side), you need to convert the table, rows and the cells to server control (using runat="server") and iterate through the controls in the table.
EDIT : :- If you are adding the rows, cells and radionbuttons following way, all of them will be the server controls (and are runat=server) so that you can access them the way I mentioned above:--
// Create new row and add it to the table.
TableRow tRow = new TableRow();
table1.Rows.Add(tRow);
for (cellCtr = 1; cellCtr <= cellCnt; cellCtr++)
{
// Create a new cell and add it to the row.
TableCell tCell = new TableCell();
RadioButton rdb = new RadioButton();
rdb.ID = "rdb_" + cellCtr.ToString();
rdb.Text = "radio button";
rdb.GroupName = "rdbGroup";
tCell.Controls.Add(rdb);
tRow.Cells.Add(tCell);
}
EDIT:-
You can find the controls in each cell.Something like below:-
foreach(TableCell cell in tableRow.Cells)
{
foreach(Control ctrl in cell.Controls)
{
if(ctrl is RadioButton)
{
if(ctrl.Selected)
{
string rdValue=ctrl.Text;
}
}
}
}
Or If you want to iterate on the client side using Javascript, have a look here and you dont have to apply runat="server".
It sounds like you're starting with a barebones <table> in your markup page, and dynamically adding those <input> afterwards.
Consider taking this approach:
Add the runat="server" attribute to your table.
In the code where you're adding those <input> tags, add a new RadioButton control. Use an ID here that you can predict later. Perhaps you can use a RadioButtonList instead, if the choices are logically grouped!
It's unclear if you're manually adding those <tr> and <td> as strings. Consider the option of new TableRow() and new TableCell(). Then add the new RadioButton to the TableCell.Controls collection with tc.Controls.Add(myNewRadioButton);
In your postback code, simply refer to your RadioButton controls by id, or even loop through the Controls collection property of the Table1.
foreach (Control x in Table1.Controls)
{
if (x.GetType().ToString().Equals("System.Web.UI.WebControls.RadioButton"))
{
if (((RadioButton)x).Checked)
{
//proceed.
}
}
}
Convert all controls to server controls (by adding the runat="server" attribute). You can then programatically access what you need o. The server.

Resources