Render view fragments directly, using thymeleaf - thymeleaf

I am trying to get just a part of the view(fragment) from a template, i just end up getting the following error
org.thymeleaf.exceptions.TemplateInputException: Error resolving template "path/to/template::fragment", template might not exist or might not be accessible by any of the configured Template Resolvers
And this is the current configuration:
TemplateResolver resolver = new ServletContextTemplateResolver();
resolver.setTemplateMode("HTML5");
resolver.setPrefix("/WEB-INF/templates/");
resolver.setCharacterEncoding("UTF-8");
resolver.setSuffix(".html");
resolver.setCacheable(false);
engine = new TemplateEngine();
engine.setTemplateResolver(resolver);
It soud be possible as it is given as a feature(but using spring-mvc, which I am not):
http://www.thymeleaf.org/whatsnew21.html#spfrag
The site application works using jsp, and the code that is failing looks like this:
render("surveys/survey", params,request,response);//This works
render("surveys/survey::surveyBody", params,request,response);//This fails
public static String render(String template,Map<String,?> context,HttpServletRequest request, HttpServletResponse response){
IContext iContext = new WebContext(request,response,request.getServletContext(),Locale.US, context);
return engine.process(template, iContext);
}
inside the template there is something like this
<div th:fragment="surveyBody">
<div th:each="field,idx : ${survey.fields}" th:id="${'field_' + field.id}" th:class="${field.type + ' row outter'}">
<input type='hidden' th:id="${'field_' + field.id + '_id'}" id='field_100_id' value='100' />
<input type='hidden' th:id="${'field_' + field.id + '_type'}" id='field_100_type' th:value='${field.type}' />
<input type='hidden' th:id="${'field_' + field.id + '_order'}" id='field_100_order' th:value='${field.obj.order}' />
<input type='hidden' th:id="${'field_' + field.id + '_outstanding'}" id='field_100_outstanding' value='-1' />
<h3 th:utext="${field.obj.title[0].title}">title</h3>
<h4 th:if="${!field.obj.subTitle.isEmpty()}" th:utext="${field.obj.subTitle[0].title}">subtitle</h4>
<div class="answers row">
<div th:replace="surveys/questions::${field.type}(${field},${disabled},${idx.index})"></div>
</div>
</div>
</div>

th:fragment is called in template using th:replace or th:include attributes.
Try to create a clear file (surveys/surveyfragment) and write there:
<div th:replace="surveys/survey::surveyBody"/>
And then call it:
render("surveys/surveyfragment", params,request,response);
Should work

Related

Why my textBoxFor type="date" doesn't display date?

I have a simple partial view where there is a TextBoxFor type = "date" (a date picker).
And when I open this partial view I would like the TextBoxFor type = "date" to display a date from the Model.
But I can't reach it, the TextBoxFor displays nothing.
The Model.Dt_Reference is well displayed in the ViewBag.Title.
Here is the partial view :
#using w_TreatmentMVC.Models
#model w_TreatmentMVC.Models.DemandeModel
#{
Layout = null;
}
#{
ViewBag.Title = "Modif demand n° " + Model.ID_DEMAND + " : " + Model.LI_TREATMENT + " : " + Model.DT_REFERENCE;
}
<h2>#ViewBag.Title.</h2>
<h3>#ViewBag.Message</h3>
<script type="text/javascript" src="../../Scripts/GlobalScripts.js"></script>
<div class="form-group">
#Html.TextBoxFor(m => m.DT_REFERENCE, new { #type = "date", #Value = Model.DT_REFERENCE.ToString("dd/MM//yyyy") })
</div>
<div class="col-lg-12 col-md-12 col-xs-12" id="divPartial">
<div class="col-lg-12 col-md-12 col-xs-12" id="divDemandOption">
#Html.Action("SearchDemandOption", "Option")
</div>
</div>
<input id="ButtonClose" type="button" value="Close" onclick="fctClose()" />
<script>
function fctClose() {
$("#divPopUpModal").fadeOut("slow");
$('#divMainModal').fadeOut("slow");
}
</script>
Could you help me ?
Thanks a lot in advance.
Eric.
If you want to set default value to date input,its value format need to be
value="yyyy-mm-dd".And if your DT_REFERENCE is datetime type,try to do like this:
<input type="date" asp-for="DT_REFERENCE" value=#Model.DT_REFERENCE.ToString("yyyy-MM-dd").Split(" ")[0] />
result:

How anchor tag is firing an HTML Action in MVC?

I have the following code:-
<div class="control-group">
<label class="control-label"><b>Contact</b> <span style="color: #f00; font-size: larger;">*</span></label>
<div class="controls input-append">
<input disabled="disabled" style="width: 210px" type="text" id="id-lookup-addjllcontact-contactid" defaultoid=""
defaultvalue="" oid="" value=""
field="SystemUserId" otype="systemuser">
<a class="btn" id="btn-lookup-addjllcontact-contactid"><i class="icon-search"></i></a>
</div>
</div>
<div>
#Html.Action("_LookupSearchPartial", "Lookup",
new
{
ParentFormId = "form-addjllcontact",
LookupInputId = "id-lookup-addjllcontact-contactid",
LookupButtonId = "btn-lookup-addjllcontact-contactid",
UniqueId = Guid.NewGuid(),
EntityType = "systemuser",
AttributeName = "systemuserid",
AttributeDisplayName = "FullName"
})
</div>
When I click anchor with id as "btn-lookup-addjllcontact-contactid", it fires the HTML Action. Can any one tell me how ? Also I want to know how can display the result of the HTML Action in a modal.
There was Javascript in the page somewhere hidden which was doing it. This was a generic javascript file that was handling all the lookups in the application.
this.lookupInput = $('#' + this._config.LookupInputId);
this.lookupButton.live("click", this, JLL.Lookup.Search.showLookup);

How to make an action in a controller receive the more data from unknown number of inputs

How to make an action in a controller to receive more data from an unknown number of inputs?
I want when click on more option for enter more information that is mean the DOM tree on HTML page is increasing for that I do not know how to make action receive data from an unknown number of inputs on HTML page.
This is my codes of html
<div class="form-group">
<label class="col-md-2 lableAlign">Course Name</label>
<div class="col-md-6">
<input class="col-md-6" type="text" name="courseTitle" id="courseTitle" value="Thamar" maxlength="20">
#Html.ValidationMessageFor(model => model.courseTitle, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<label class="col-md-2 lableAlign">Certificate</label>
<div class="col-md-6">
<input class="col-md-6 r" type="file" name="courseCertificate" id="courseCertificate" val`enter code here`ue="">
#Html.ValidationMessageFor(model => model.courseCertificate, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group more" id="corceMore">
<label class="col-md-3 more" onclick="corceAdd()">More +</label>
</div>
And this is my javascript code
function corceAdd() {
++corcecount;
if (corcecount < 20) {
$("<div class=\"divStyle\"><div class=\"form-group\"><label class=\"col-md-2 lableAlign\">اسم الدورة</label><div class=\"col-md-6\"><input class=\"col-md-6\" type=\"text\" name=\"corceTitle" + corcecount + "\" id=\"corceTitle" + corcecount + "\" value=\"\"></div></div><div class=\"form-group\"><label class=\"col-md-2 lableAlign\">الشهادة</label><div class=\"col-md-6\"><input class=\"col-md-6 r\" type=\"file\" name=\"corceCertificate" + corcecount + "\" id=\"corceCertificate" + corcecount + "\" value=\"\"></div></div>").insertBefore("#corceMore");
}
}
when click on more option the new element its id and name with increasing by one , Now my problem is when I click on submit I want send all elements values to a post action in a controller .
There are lots of articles and topics about this question:
http://techiesweb.net/2012/09/17/asp-net-mvc3-dynamically-added-form-fields-model-binding.html
ASP.NET MVC Dynamic Forms
I will show the main point. How to bind dynamically input to action model.
You need to have a collection as a model.
public class SampleViewModel
{
public IEnumerable<SampleItemViewModel> Items {get;set;}
}
public class SampleItemViewModel
{
public string Id {get;set;}
}
Then in the Razor view you should create an input like this:
<input id='Items__0__Id' type='hidden' name='Items[0].Id' />
<input id='Items__1__Id' type='hidden' name='Items[1].Id' />
So you should bind name of the input to the property of the collection with index. Then in your action:
public ActionResult Post(SampleViewModel model)
{
var items = model.Items; // Here you should have your collection
}

How to bind data from model to view using knockoutJS

in my application i'm able to get data-collection from model when i'm binding it using knockoutJS that it generate an error on console, i need with data-bind attribute data-class, i'm doing so but not working;
my view binding code as :
<div class="filter-map-content" data-bind="foreach: { data: Services, as: 'service' }">
<input type="checkbox" class="custom-checkbox" data-bind="css: { 'id': service.id, 'data-class': 'GTM_MMCheckbox_' + service.title + '_' + service.id }" data-class=" 'GTM_MMCheckbox_' + service.title + '_' + service.id" />
</div>
i'm able to get data collection when i write it on console , i'm getting data collection as result
data-class is not finding in my javascript code
but data-collection is available
<div class="filter-map-content" data-bind="foreach: { data: Services, as: 'service' }">
<input type="checkbox" class="custom-checkbox" data-bind="attr: { 'id': service.id, 'data-class': 'GTM_MMCheckbox_' + service.title + '_' + service.id }" />
</div>
you have to use the "attr"-binding ;)
...and if your "service.title" or "service.id" is observable you have to write e.g. service.title()

How to write the following in MVC?

How can I write the following in MVC?
<input type="text" name="ProjectList[' + count++ + '].ID" value = ' + value + ' />
Use code expressions in <%= ... %> block in the attributes.
<input type="text" name="<%= ProjectList[count++].ID %>" value = ' + value + ' />
If the value is meant to be another property of the ProjectList item... then setting a local variable would be easier:
<% var item = ProjectList[count++].ID; %>
<input type="text" name="<%= item.ID %>" value = '<%= item.value %>' />
Albeit that the HTML helpers (see other answer) provides a better approach.
NB. In .NET 4 prefer <%: ... %> to ensure things are HTML Encoded.
<%= Html.TextBox("ProjectList[" + (count++) + "].ID",
value, new { #class = "css" }) %>

Resources