How can I send any parameter to change something in the model?
I tried with setters but failed, and when tried to do it from the view I got a strange behaviour.
This is as far as I'm now.
HTML:
Selected name: <span data-bind="text: selectedName"></span>
<ul data-bind="foreach: names">
<li>
<a data-bind="text: $data, click: $root.nameSelected" href="#"></a>
</li>
</ul>
<hr>
<a data-bind="text:'hi',click: $root.nameSelected('hi')" href="#"></a>
Java:
package dew.demo.namesmodel;
import net.java.html.json.Model;
import net.java.html.json.Property;
import net.java.html.json.Function;
#Model(className="Names", properties={
#Property(name = "selectedName", type=String.class),
#Property(name = "names", type=String.class, array = true)
})
class NamesModel {
#Function static void nameSelected(Names myModel, String data) {
myModel.setSelectedName(data);
}
static {
Names pageModel = new Names(
"---", "Jarda", "Pepa", "Honza", "Jirka", "Tomáš"
);
pageModel.applyBindings();
}
}
you can see the example running on this fiddle.
It is possible to workaround the problem by using with binding:
<div data-bind="with: 'hi'">
<a data-bind="text: $data,click: $root.nameSelected" href="#"></a>
</div>
as your updated DEW shows.
The example seems to fail only in DEW. I created a normal DukeScript project, where it works fine, also when running in a browser. So I assume this is simply a bug in DEW.
Related
I'm new to aurelia. I'm looking to find the best method for adding classes on click events.
I simply want to click approve or request information, and then add a class to the corresponding "contact card". This class would change the background color.
I know it's probably simple, but I thought I'd look here for the best method.
Here's an image to what I've got:
Apologies for the wait, work has been a bit busy.
This is my first time posting on S.O., so I apologize for any expectations I'm not meeting.
<div class="col-sm-4">
<button class="btn btn-success col-sm-12" click.delegate="goodBoi()">
approve contact
</button>
</div>
<div class="col-sm-4">
<button class="btn btn col-sm-12" click.delegate="requestContact()">
request information
</button>
</div>
</div>
the element to be changed is named "list-group-item", containing the
contact's details(code shown above).
<template>
<div class="contact-list">
<ul class="list-group">
<li repeat.for="contact of contacts" class="list-group-item ${contact.id === $parent.selectedId ? 'active' : ''}">
<a route-href="route: contacts; params.bind: {id:contact.id}" click.delegate="$parent.select(contact)">
<h4>${contact.firstName} ${contact.lastName}</h4>
<p>${contact.company}</p>
<p>${contact.email}</p>
<h6>${contact.approval}</h6>
</a>
<a route-href="route: contacts; params.bind: {id:contact.id}">
<p>${contact.phoneNumber}</p>
</a>
</li>
</ul>
</div>
goodBoi() {
let result = confirm("Are you sure you want to confirm this contact?");
if (result === true) {
var standingShell = document.getElementsByClassName("list-group-item");
//im hoping here I would add a class to the new variable//
this.contact.approval = 'approved';
this.save();
}
}
//confirms contact, changing color of approved contact//
//same thing here, just plan to give it a different color//
requestContact() {
let contactRequestText = "request sent to contact";
this.routeConfig.navModel.setTitle(this.contact.approval = contactRequestText);
this.ea.publish(new ContactUpdated(this.contact));
}
There are many ways to set a CSS-class using Aurelia. Following I prepared an example gist:
Template:
<template>
<h1>${message}</h1>
<div class="form-group ${clicked ? 'red' : 'blue'}" style="width: 100px; height: 100px;">
</div>
<div class="form-group">
<button click.delegate="save()">
Click me
</button>
</div>
</template>
And the code class:
#autoinject
export class App {
#bindable clicked = false;
save(){
this.clicked = true;
}
}
https://gist.run/?id=425993b04a977466fa685758389aa2b4
But there are other, cleaner ways:
using ref in a custom element.
custom attributes.
Include jQuery for using e.g. $('#myelement').addClass()
I've made a menu showing systems and their subsystems (can in theory be indefinitely) using a recursive component. A user can both add and delete systems, and the menu should therefore update accordingly.
The menu is constructed using a "tree"-object. This tree is therefore updated when a new system is added, or one deleted. But, I now have a problem; even though the new child component is added when the tree is rerendered, the classes of it's parent-component doesn't update. It is necessary to update this because it defines the menu-element to having children/subsystems, and therefore showing them.
Therefore, when adding a new subsystem, this is presented to the user:
<div class="">
<a href="#/Admin/364" class="item">
<i class=""></i>Testname
<div class=""></div>
</a>
</div>
Instead of this:
<div class="menu transition visible" style="display: block !important;">
<a href="#/Admin/364" class="item">
<i class=""></i>Testname
<div class=""></div>
</a>
</div>
It works fine adding a subsystem to a system which already have subsystems (since the menu-class is already present), but not when a subsystem is added to one without subsystems. In that case, the menu ends up looking like this:
The "opposite" problem also occurs on deletion, since the parent still has the menu-class:
Here's the code for the recursive component:
<template>
<router-link :to="{ name: 'Admin', params: { systemId: id } }" class="item" >
<i :class="{ dropdown: hasChildren, icon: hasChildren }"></i>{{name}}
<div :class="{ menu: hasChildren }">
<systems-menu-sub-menu v-for="child in children" :children="child.children" :name="child.name" :id="child.id" :key="child.id"/>
</div>
</router-link>
</template>
<script type = "text/javascript" >
export default {
props: ['name', 'children', 'id'],
name: 'SystemsMenuSubMenu',
data () {
return {
hasChildren: (this.children.length > 0)
}
}
}
</script>
I'm guessing this has to do with Vue trying to be efficient, and therefore not rerendering everything. Is there therefore any way to force a rerender, or is there any other workaround?
EDIT: JSFiddle https://jsfiddle.net/f6s5qzba/
I would like to find a complete solution to Thymeleaf pagination using Spring PagingAndSortingRepository DAO. I got a partial solution working, but I can not get the final one. I think it would be interesting for everyone else as a code snipet, so I will ask for the whole thing. I could not find a solution on the web which is kind of strange for me (since I think it could be a quite common problem).
The final solution should behave like Google's pagination: with arrows on both sides only if it makes sense; with a maximun of 10 numbers (for example), and it should move from 1..10 --> 11..20 and so on, when you click the right arrow; and move to 5..15 when you click on 10. Just like google, you know. The size controls the number of items in each page, not the number of blocks or links in the pagination bar.
I have a DAO repository in Spring that extends PagingAndSortingRepository ...
package music.bolo.domain.repository;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;
import music.bolo.domain.entity.Announcement;
#Repository public interface AnnouncementDao extends
PagingAndSortingRepository {
Announcement findFirstByOrderByDateDesc(); }
So my service can make a request and each page will get the totalPageNumbers (http://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/domain/Page.html)...
private final static int PAGESIZE = 2;
.. .. #Autowired annotations...
public Page<Announcement> readAnnouncementPage (int pageNumber){
PageRequest request = new PageRequest(pageNumber-1, PAGESIZE, Sort.Direction.DESC, "date");
return announcementDao.findAll(request); }
My Controller uses the data to send all the information to Thymeleaf
#RequestMapping(value = "/viewannouncements", method = RequestMethod.GET)
ModelAndView viewAnnouncements(ModelAndView modelAndView, #RequestParam(name = "p", defaultValue = "1") int pageNumber) {
Page<Announcement> page = announcementService.readAnnouncementPage(pageNumber);
modelAndView.getModel().put("page2th", page);
modelAndView.setViewName("viewannouncements");
return modelAndView; }
My solution is partial, it shows all the pages all the time, no arrow control (actually useless) and without any other funcionality, but it is the most I could make it work without bugs.
<div class="tag-box tag-box-v7 text-justify">
<!-- <h2>Pagination Centered</h2>-->
<div class="text-center">
<ul class="pagination">
<li>«</li>
<!--<li>«</li>-->
<li th:each="i : ${#numbers.sequence( 1, page2th.TotalPages)}">
<a th:href="#{'/viewannouncements?p='}+${ i }" th:text="${ i }">1</a></li>
<!--<li>»</li>-->
<li>»</li>
</ul>
</div>
</div>
This is an example of pagination with SpringBoot and Thymeleaf templates, you can try it.
It is self-explanatory.
Following you can find link to GitHub repo -
https://github.com/karelp90/control_asp
<div class="tag-box tag-box-v7 text-justify">
<div class="text-center">
<ul class="pagination" th:with="elementsperpage=2, blocksize=10, pages=${page2th.Number}/${elementsperpage}, wholepages=${format.format(pages)},
whole=(${page2th.Number}/${blocksize})+1, wholex=${format.format(whole)}, startnlockpage=${wholepages}*${blocksize+1}, endblockpage=${wholepages}*${blocksize+1},
startpage=${wholex-1}*${blocksize}, endpage=(${wholex}*${blocksize})+1">
<li>
<a th:if="${startpage gt 0}" th:href="#{${'/viewannouncements?p='}+${startpage}}"><<</a>
<a th:if="${startpage eq 0}" href="javascript:void(0);"><<</a>
</li>
<li th:each="pageNo : ${#numbers.sequence(endpage-11, (endpage lt page2th.TotalPages)? endpage-2 : page2th.TotalPages-1)}"
th:class="${page2th.Number eq pageNo}? 'active' : ''">
<a th:if="${page2th.Number eq pageNo}" href="javascript:void(0);">
<span th:text="${pageNo + 1}"></span>
</a>
<a th:if="${not (page2th.Number eq pageNo)}" th:href="#{${'/viewannouncements?p='}+${pageNo+1}}">
<span th:text="${pageNo + 1}"></span>
</a>
</li>
<li>
<a th:if="${(endpage*elementsperpage) le (page2th.TotalElements)}" th:href="#{${'/viewannouncements?p='}+${endpage}}">>></a>
<a th:if="${(endpage*elementsperpage) le (page2th.TotalElements)}" href="javascript:void(0);"></a>
</li>
</ul>
</div>
</div>
Still new to selenium and css/xpath locators. I stumbled across a problem where CSS works but the equivalent XPath doesn't, and I'd really like to know why. I'm using Scala in the examples but it's still the normal Java Selenium2 library. I also use the FirefoxDriver
Here's the interesting part of the HTML:
...
<li class="k-item k-filter-item k-state-default k-last" role="menuitem" style="z-index: auto;">
...
<form class="k-filter-menu k-secondary">
<div>
<div class="k-filter-help-text">Show items with value that:</div>
<span class="k-widget k-dropdown k-header" style="" unselectable="on" role="listbox" aria-haspopup="true" aria-expanded="false" tabindex="0" aria-owns="" aria-disabled="false" aria-readonly="false" aria-busy="false">
<span class="k-widget k-datetimepicker k-header" style="">
<div>
<button class="k-button" type="submit">Filter</button>
<button class="k-button" type="reset">Clear</button>
</div>
</div>
</form>
</li>
...
I'm getting the li with
val filter = driver.findElement(By.cssSelector("li.k-filter-item"))
which works for me.
Then, I want to find the button. It's a dynamic menu thingy sliding out and what not, so I need to wait for it to appear:
new WebDriverWait(driver, selectorTimeout).until(
new ExpectedCondition[Boolean] {
override def apply(d: WebDriver) = {
filter.findElement(By.cssSelector("button[type=submit]")).isDisplayed
}
})
And that works nicely, too. My question is, why doesn't the xpath equivalent work:
new WebDriverWait(driver, selectorTimeout).until(
new ExpectedCondition[Boolean] {
override def apply(d: WebDriver) = {
filter.findElement(By.xpath("//button[#type='submit']")).isDisplayed
}
})
Anybody?
[EDIT]
Selenium version: 2.35.0
FireFox driver: 2.35.0
I will try it with Opera now.
You'll need the . in front of the XPath selector anyway, so that it'll search the current element's descendants/children:
.//button[#type='submit']
Sometimes, a more elaborate XPath can also help:
.//descendant::button[#type='submit']
I'll start by saying that I am working within the context of DotNetNuke7, which is essentially ASP.net based framework, and that i am fairly new to KO.
I am trying to have one ko viewmodel and have two foreach loops in it. Each loop renders an array which is part of the view model definition like so:
//We build two arrays: one for the users that are in the group
//and one for the users that are not in the group
var nonGroupMembers = $.map(initialData.NonGroupUsers, function (item) { return new Member(item); });
var groupMembers = $.map(initialData.GroupUsers, function (item) { return new Member(item); });
//The members we start with before we added new members
self.SearchTerm = ko.observable('');
self.CircleMembers = ko.observableArray(groupMembers);
self.NonCircleMembers = ko.observableArray(nonGroupMembers);
In the html context (or the asp user control) i placed the following code
<div id="socialDirectory" class="dnnForm dnnMemberDirectory">
<ul id="mdMemberList" class="mdMemberList dnnClear" style="display:none"
data-bind="foreach: { data: NonCircleMembers, afterRender: handleAfterRender },
css: { mdMemberListVisible : Visible }, visible: HasMembers()">
<li class="memberItem">
<div data-bind="visible: $parent.isEven($data)">
<%=MemberItemTemplate %>
</div>
<div data-bind="visible: !$parent.isEven($data)">
<%=MemberAlternateItemTemplate %>
</div>
</li>
</ul>
</div>
<div class="circleDirectory" id="circleDirectory" >
<ul id="cdMembersList" data-bind =" foreach: {data: CircleMembers, afterRender: handleAfterRender}">
<li class="memberItem">
<div class="mdMemberDetails">
<a href="" class="mdMemberImg" data-bind="attr: { title: DisplayName, href: ProfileUrl }">
<span><img data-bind="attr: { src: getProfilePicture(50,50), title: DisplayName }" /></span>
</a>
<ul class="MdMemberInfo">
<li class="mdDisplayName" >
<a href="" title="" class="mdMemberTitle"
data-bind="attr: { title: DisplayName, href: ProfileUrl },
event: { mouseover: $parent.showPopUp }">
<span data-bind="text: DisplayName"></span>
</a>
</li>
<li class="mdTitle"><p><span data-bind="text: Title"></span></p></li>
<li class="mdLocation"><p><span data-bind="text: Location()"></span></p></li>
</ul>
</div>
</li>
</ul>
</div>
Each one of the DIVs which contain the foreach binding loop in them works perfectly well without the other. For instance, the bottom div (id= cdMembersList) will work fine but when I add the upper div with the binding markups it will stop working. The same thing happens vise verse.
Does anybody have a clue why it might happen? Can i not have 2 loops in one view model?
looking forward to solving this mystery.
thanks,
David
Ok, I hate to say it but the answer is very simple as always. I didn't add to my view model the Visible property for
css: { mdMemberListVisible : Visible }
When I created a new script file I simply skipped this property. A few lessons:
You can run more than one loop in one view model.
Always check that you have all the properties defined in the view model.
Also, apparently it helps creating a question on this board since it makes you think clearly about the problem and revisit your actions. I had spent 2 hours chasing this problem before i posted my question, and then it took me 15 minutes to solve it after I posted it.