I am using ASP.Net MVC and have following code.
#
{
int id=0;
}
#foreach(var item in (<IEnumerable>Problem)ViewBag.Problems
{
<div>
<h2> <a href="#" id=#id onclick="IncrementVisits(this)" > #item.Subject </a> </h2>
#id++ -----Special Line 1
Visit(<span id="#id">#item.Visits</span>)
<hr />
</div>
<br />
id++; ------Specila Line 2
}
Problem is that in Special Lines 1 and 2( which i have given these name just for understanding ) i want to increment value in id but don't want to show in div. How to avoid with this that value in id should not be displayed in div and increment should also be done. Please help.
In both cases you should use a code block:
#{
id++;
}
Opposite to expressions (i.e. #id++), code blocks don't produce any default output.
Related
I have a Spring MVC application using Thymeleaf for templating. I am using enums to generate checkboxes dynamically. So if my enum file has 3 values it will generate 3 checkboxes:
My enum file:
public enum Foods {
PIZZA("Pizza"),
PASTA("Pasta"),
MAC_CHEESE("Mac and Cheese"),
ICE_CREAM("Ice Cream"),
BURGER("Burger"),
private String type;
Foods(String type) {
this.type = type;
}
public String getType() {
return this.type;
}
}
This is my checkbox generation:
<label for="decision">What is your favorite food?</label>
<div id="decision" class="row" style="margin-top:1%;">
<div class="col-md-4" th:each="option : ${T(in.app.model.enums.Foods).values()}">
<div class="checkbox checkbox-custom checkbox-circle">
<input name="decision" type="checkbox" th:id="${option.toString()}" th:value="${option}" />
<label th:for="${option.toString()}" th:text="${option.type}"></label>
</div>
</div>
</div>
This code will generate 5 checkboxes for each of the food type. All works till here. The issue I am facing is how to set the checked attribute when reading a saved record.
I am getting back an object via the model view controller. The object has a food property with its value as the array of the chosen food types.
user = {
.
.
food : ["PIZZA", "BURGER", "PASTA"],
.
.
}
Now I want to loop through this array and if the value match then set the checkbox.
I am trying to do something like this:
<label for="decision">What is your favorite food?</label>
<div id="decision" class="row" style="margin-top:1%;">
<div class="col-md-4" th:each="option : ${T(in.app.model.enums.Foods).values()}">
<div class="checkbox checkbox-custom checkbox-circle">
<input
name="decision"
type="checkbox"
th:id="${option.toString()}"
th:value="${option}"
th:each="food : ${user.food}"
th:attr="checked = ${food} == ${option} ? 'checked'"
/>
<label th:for="${option.toString()}" th:text="${option.type}"></label>
</div>
</div>
</div>
I know its wrong (since its not working) but I am unable to figure out how to loop over two arrays to show the checkboxes and to check them.
You might want to try using th:checked instead of th:attr if you can, so:
th:checked="${food == option.type}"
This post might also be helpful when looking into that. If you can't use th:checked, switching to the below statement should also work.
th:attr="checked=${food == option.type} ? 'checked'"
It also seems like you may run into some issues with checking this data due to case sensitivity while comparing, in which case this post might be helpful.
The safe option is to go with
th:attr
and do compare like #Artichoke
th:attr="checked=${food == option.type} ? 'checked'"
The problem with "th:checked" is, its simply do not go well when you need to post the data unless you change the value. You see its value as null if you do not switch it.
I have a See more button which when clicked I want to be able to load another 3 Past Events onto the default 3 past events that show on page load, and then if clicked again, add another 3 etc.
The code below works but is multiplying the number for some reason e.g if I press the "See more" button as the code is now, it returns 18 past events when it should only return 6 past events...
If I dd($amountOfCurrentPastEvents + 3) I get int(6) returned 3 times, 6 x 3 = 18. e.g:
Question is why is it getting called three times? What am I doing wrong here?
DashboardPage.php
class DashboardPage_Controller extends Page_Controller {
private static $allowed_actions = array(
'pastEvent',
'seeMorePastEvents',
'pasteventfilter',
'LimitedPastEvents'
);
public function LimitedPastEvents()
{
return PastEvent::get()->limit(3);
}
public function seeMorePastEvents() {
if (Director::is_ajax()) {
// Gets the amount of past events that are display on the page at present
$amountOfCurrentPastEvents = $_POST['events'];
// Adds 3 onto how ever many past events are currently showing
$PastEvents = PastEvent::get()->limit($amountOfCurrentPastEvents + 3);
return $this->customise(array(
'Results' => $PastEvents
))->renderWith('AjaxPastEvents');
}
}
...
}
DashboardPage.ss
<% loop LimitedPastEvents %>
<div class="past-event-results">
<div class="col-md-4 no-padding past-event">
<a href="$Link">
<div class="live-workouts-wrapper">
<div class="on-demand-image" style="background-image: url($ThemeDir/images/vid-3.jpg);">
<div class="play-icon"></div>
</div>
<div class="on-demand-info text-center">
<div class="on-demand-location">
<span class="pin-icon"></span><span>$BranchLocation.Name, $BranchLocation.City</span>
</div>
<div class="on-demand-date-time">
<span class="time-icon"></span>
<span>{$EventDate.Day} {$EventDate.ShortMonth} {$EventDate.Format(dS)} $Time.Nice</span>
</div>
<div>
<strong>$EventName</strong>
</div>
</div>
</div>
</a>
</div>
</div>
<% end_loop %>
<div class="col-md-12">
<div class="text-center">
<button class="btn btn-seemore">SEE MORE<b class="btn-icon btn-down"></b></button>
</div>
</div>
jQuery - Located on DashboardPage.ss
<script>
$(document).ready(function() {
var pastEventCount;
$('.btn-seemore').on('click', function(event) {
event.preventDefault();
// Gets the amount of past events that are currently displayed on the page
pastEventCount = $('.past-event').length;
console.log(pastEventCount);
$.post('/dashboard/seeMorePastEvents', {events: pastEventCount}, function(data) {
$('.past-event-results').html(data);
});
});
});
</script>
The problem is the code adds the new content to .past-event-results with $('.past-event-results').html(data);, but the template has 3 .past-event-results divs to begin with.
The data returned by the ajax function (6 PastEvent entries) is added to 3 divs, making the results show 18 items.
The following loop creates 3 past-event-results divs to begin with:
<% loop LimitedPastEvents %>
<div class="past-event-results">
...
</div>
<% end_loop %>
You might want to take this div outside of the loop:
<div class="past-event-results">
<% loop LimitedPastEvents %>
...
<% end_loop %>
</div>
This will mean there is only ever one past-event-results div.
I would also recommend changing the seeMorePastEvents() function to only return the new items, rather than all the existing items plus the new items each time. This will save on data that needs to be passed back and slightly improve the server fetch.
To make this change we first need to change the limit function to only fetch 3 items and start the fetch from the $amountOfCurrentPastEvents point.
$PastEvents = PastEvent::get()->limit(3, $amountOfCurrentPastEvents);
The DataList limit() function can take 2 parameters:
limit(integer $limit, integer $offset = 0)
We use offset to change the fetch start point.
We then change our JavaScript to append the retrieved data rather than overwrite the existing events:
$('.past-event-results').append(data);
At first glance it looks like a JS issue.
You might have x3 AJAX requests being sent - if you break out your browser's debugger, how many XHR requests are being sent to SilverStripe?
Also check the generated markup. I suspect your JS logic should be appending to the .past-event-results DOM node itself, and not appending to its contents which is essentially what the jQuery html method is doing for you.
I've created a multinode tree picker datatype and i'm trying to list the thumbnails of a vehicle as part of the foreach loop, however i keep getting ID rendering in the src of the image, i'm having trouble getting the URL of the image.
MVC Razor Code
#inherits Umbraco.Web.Macros.PartialViewMacroPage
#using Umbraco.Web
#*
Macro to list nodes from a Multinode tree picker, using the pickers default settings.
Content Values stored as xml.
To get it working with any site's data structure, simply set the selection equal to the property which has the
multinode treepicker (so: replace "PropertyWithPicker" with the alias of your property).
*#
#* Lists each selected value from the picker as a link *#
<div class="featuredVehicles">
#foreach (var id in CurrentPage.featuredVehicles.Split(','))
{
#*For each link, get the node, and display its name and url*#
var vehicleContent = Umbraco.Content(id);
<div class="col-xs-6 col-md-4 col-xs-height">
<a href="#vehicleContent.Url">
#if (vehicleContent.HasValue("vehicleThumbnail"))
{
var mediaItem = Umbraco.TypedMedia(vehicleContent.GetPropertyValue("vehicleThumbnail"));
<img class="featuredVehicleImg img-responsive" src="#vehicleContent.GetPropertyValue("vehicleThumbnail")" alt="#vehicleContent.Name"/>
}
else
{
<img class="comingSoon" src="http://placehold.it/650x408" alt="#vehicleContent.Name">
}
<strong>
<span class="name">#vehicleContent.Name</span>
</strong>
<span class="desc">#vehicleContent.GetPropertyValue("shortContent")</span>
<span class="prx">from, <strong>£#vehicleContent.vehiclePrice</strong> per day</span>
<span class="label label-primary moreinfo">More Info</span>
</a>
</div>
}
</div>
HTML
<img alt="Pharmaceutical Vehicle One" src="1092" class="featuredVehicleImg img-responsive">
Problem solved;
This is the bit where the problems were being caused;
if (vehicleContent.HasValue("vehicleThumbnail")){
var dynamicMediaItem = Umbraco.Media(vehicleContent.vehicleThumbnail);
<img src="#dynamicMediaItem.umbracoFile" alt="#dynamicMediaItem.Name"/>
}
else
{
<img class="comingSoon" src="http://placehold.it/650x408" alt="#vehicleContent.Name">
}
Hopefully it will help someone else out :-)
I'm having a problem and i'm really puzzled by it.
My markup is simple enough:
#foreach (var item in Model.Items)
{
<a class="mapIconUnit" id="pinDelete-#item.PinGuid.ToString()">
#Url.Action("DeletePin") <!-- testing purposes -->
#(Ajax.ActionLink("x", "DeletePin", MapAdministrationController.Routes.DeletePin(item.PinGuid), new AjaxOptions()
{
OnSuccess = "onMapPinDeleted",
Confirm = Resources.Resource.msg_GenericDeleteConfirmationQuestion
}
))
</a>
}
Now what i would expect to render from this is:
<a class="mapIconUnit" id="...">
... rendered url
<a href="..." etc>x</a>
</a>
But what i am getting is:
<a class="mapIconUnit" id="...">
... rendered url
</a>
<a href="..." etc>x</a>
What am i doing wrong here? The markup is too simple for it to be wrong to cause such a thing?
It's illegal to nest an anchor element inside another anchor element, more info can be found in the W3C specs: http://www.w3.org/TR/html401/struct/links.html#h-12.2.2
Links and anchors defined by the A element must not be nested; an A element must not contain any other A elements.
So either razor or the webbrowser renders the elements correctly (i.e. place them next to each other).
I'm working with share forms in alfresco and trying to read the values of ticked checkboxes and checked radio buttons form a form. I extended both the user creation and userprofile form with these input controls and so far I have been unsuccessful at reading the textual values of said controls. Below is a snippet of code:
<div class="row">
<span class="label"><input id="${el}-input-spokenEnglish" type="checkbox" name="spokenLanguages" value="${msg("label.anglais"!"")?html}" /> ${msg("label.anglais")}</span>
<span class="label"><input id="${el}-input-spokenSpanish" type="checkbox" name="spokenLanguages" value="${msg("label.espagnol"!"")?html}" /> ${msg("label.espagnol")}</span>
<span class="label"><input id="${el}-input-spokenGerman" type="checkbox" name="spokenLanguages" value="${msg("label.allemand"!"")?html}" /> ${msg("label.allemand")}</span>
<span class="label"><input id="${el}-input-spokenChinese" type="checkbox" name="spokenLanguages" value="${msg("label.chinois"!"")?html}" /> ${msg("label.chinois")}</span>
<br/>
<span class="label">${msg("label.otherLanguages")} : </span>
<span class="input"><input id="${el}-input-spokenLanguages" type="text" size="30" maxlength="256" value="" <#immutablefield field="spokenLanugages" /> /> </span>
</div>
unfortunately I get nothing so far from whatever is returned and would gladly appreciate some insight into this.fre
If you look at userprofile.get.html.ftl, you'll see the following snippet:
<script type="text/javascript">//<![CDATA[
var userProfile = new Alfresco.UserProfile("${args.htmlid}").setOptions(
{
This means it's triggering a client-side JS file from Alfresco, in this case profile.js (see the head file). So just adding some input fields isn't enough.
You need to extend the client-side JS file.
In the function onEditProfile it gets the Dom elements.
But that's just for showing the actual fiels 'after' it's saved.
In profile.js you'll see: form.setSubmitAsJSON(true); that you have a json object from which you can get your fields.
And in userprofile.post.json.ftl it does a loop on the user.properties:
for (var i=0; i<names.length(); i++)
{
var field = names.get(i);
// look and set simple text input values
var index = field.indexOf("-input-");
if (index != -1)
{
user.properties[field.substring(index + 7)] = json.get(field);
}
// apply person description content field
else if (field.indexOf("-text-biography") != -1)
{
user.properties["persondescription"] = json.get(field);
}
}
user.save();
This probably means that you haven't extended the contentmodel of the cm:person object with your new properties.