I am currently making a form for film database, using Vaadin. My problem is the whole situation with deep linking. I want to have a url with an id of movie in it, to make possible to get to the form of concrete movie.
localhost:port/filmView/idOfSelectedMovie
I am currently using pushState but there are couple of problems.
1) When I add string "Film/" before Id, the first selection works fine, however with following selections the url just keeps adding this.
http://localhost:8081/Film/Film/Film/Film/Film/4
2) The second option I tried was using just an id. The effect was that the url just keeps the host with port, and gets rid of ViewName
http://localhost:8801/4
I had already tried to use replaceState and Urifragment methods, the effect wasn't better at all.
the function handling selection of movie on the list
this.itemsList.addSelectionListener(selectionEvent -> {
if (selectionEvent.getFirstSelectedItem().isPresent()) {
Film selectedFilm = selectionEvent.getFirstSelectedItem().get();
this.setupForm(selectedFilm);
Page.getCurrent().pushState("Film/" + selectedFilm.getFilmId());
}
});
What you have to do while navigating between views this: let's say you have a View with a list of films, from you can select a film. When you select a film from that list, you move to the film View
getUI().getNavigator().navigateTo(FilmView + "/" + filmId); //let's say id 88
in this way, you will navigate to http://localhost:8081/Film/88
now, in your FilmView you can get and use this id, something like:
public class FilmView extends VerticalLayout implements View{
#Override
public void enter(ViewChangeEvent event) {
String yourPassedId = event.getParameters();
//do stuff with your id, for example loading from DB
}
}
In this way, you can reach every film you want with hard link, like http://localhost:8081/Film/88
Related
I'm building a web application with spring-data-rest.
I want to show data from a big db-table in a paginated table in my frontend. The table loads asynchronically just the current page from the API. That works all fine and dandy out of the box by just having a repository like
public interface KeywordRepository extends JpaRepository<Keyword, String>, QuerydslPredicateExecutor<Keyword> {
}
Now I want to implement a functionality to jump in my paginated table to the correct page where a certain item is.
Problem is that I don't know on what page that specific item is.
I need some kind of endpoint to tell me the page number of a specific item (by id) according to the current filter- and sorting-parameters. Basically findPageOfItemById(Long id, Pageable pageable).
How can I get this?
Since the table is quite big, I don't want to have the whole content in memory.
For the sake of completeness, I'll answer my own question.
It works quite nice and without loading the whole list into memory as reqested.
But I was still hoping to find a little more spring-data-resty answer.
#GetMapping("/getPositionOfItem/{id}")
public long getPositionOfItem(#PathVariable String id, #QuerydslPredicate(root = SomeEntity.class) Predicate predicate, Pageable pageable) {
Iterable<SomeEntity> elements = someEntityRepository.findAll(predicate, pageable.getSort());
return findFirst(elements.iterator(), id);
}
private long findFirst(Iterator<SomeEntity> iterator, String id) {
long index = 0;
while (iterator.hasNext()) {
if (iterator.next().getId().equals(id)) {
return index;
}
index++;
}
return -1;
}
Note that I calculate the position of the item. To get the page of the element, we need to divide by the pagesize.
I have made a JFrame form and a database that feeds data from a jTable into one of the panels of the JFrame form. When the user types in something to the jTextField used as a search bar, the SEARCH query displays the whole table and not just a specific record. I have no idea how to add a WHERE condition to the code.
As of right now, the user can type anything in the search bar, press the search button and view all the information in the database. I tried using the statement :
myDataObj = myStatObj.executeQuery ("Select* from Gabrielle.PlantData where PName = 'search'");
but all this shows is a blank table.
Connection myConObj = null;
Statement myStatObj = null;
ResultSet myDataObj = null;
public WikiPlantGUI()
{
initComponents();
selectionAll();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
public void selectionAll()
{
try
{
myConObj= DriverManager.getConnection ("jdbc:derby://localhost:1527/InfoDB", "Gabrielle", "plants");
myStatObj = myConObj.createStatement();
myDataObj = myStatObj.executeQuery ("Select* from Gabrielle.PlantData where PName = 'search'");
guiTable.setModel(DbUtils.resultSetToTableModel(myDataObj) );
}
//Then there is some code that creates the JFrame form
private void mainSearchbtnActionPerformed(java.awt.event.ActionEvent evt) {
boolean valid = true;
String search = mainSearch.getText();
if (search.length() ==0)
{
valid = false;
}
else
{
basePanel.removeAll();
basePanel.add(dispPanel);
basePanel.repaint();
basePanel.revalidate();
}
I created the database using the design view, so I don't know how to show the code. The database has the following fields:
ID (the primary key),
PName (the field involved in the search),
PLevel,
PArea,
PType,
PWater,
PSun.
All of them are VARCHAR, except for PSun, which is INTEGER.
What I want to do now is to take data that the user has entered in a jTextField (saved as String search), search for that data in a database,and then display only the single record in the table where the data the user has entered matches a certain field in the table called PName.
I apologise if anything is too general, this is my first time using this website. Please try to use simple explanations, because I am also relatively new to programming. Any help is appreciated.
I appreciate the answers so far, but I have changed the program so much that it is unrecognizable.
The mistake I made was trying to manage the database and the GUI in the same program. I have now broken the program up into two pieces. There is the main class called "Backend" which manages reading in data from the database. There is then another class called "GUI" that handles the display of the information that is gotten from the Backend class.
As a result, much of the program's functions have changed.
I'm trying to sort through ParseObjects created by different users (clubadmins) and presenting the results based on "clubAdmin" in a recyclerview. For some reason I can't put my finger on, the query is not yielding any results to populate my view.
The line that seems to be the problem is where I query to sort using whereEqualTo().
Any help with what might be the problem is much appreciated.
The .toString() was the latest addition which also did not resolve the issue.
ParseQuery<Club> query = ParseQuery.getQuery(Club.class);
query.whereEqualTo("clubAdmin",ParseUser.getCurrentUser().toString());
query.orderByAscending("createdAt");
query.setLimit(MAX_CLUBS_TO_SHOW);
query.findInBackground(new FindCallback<Group>() {
#Override
public void done(List<Club> objects, ParseException e) {
if(e == null) {
for (Club c : objects) {
Club createdClub = new Club();
createdClub.setClubName(c.getClubName());
createdClub.setObjectId(c.getObjectId());
listItems.add(createdClub);
I was aiming for a list with the clubs created by the logged in user barring all others. Now I do not see anything in my view. If I comment out the line containing whereEqualTo(), I get all the clubs created within the app populating my view set to the limit.
What is the type of clubAdmin field? Is it a pointer to user class or a String holding the objectId of a user? If it is the second case, you have to get the objectId of the user like ParseUser.getCurrentUser().getObjectId();
This is my zul code:
<combobox id="digitalPublisherCombobox" value="#load(ivm.inventory.digitalPublisherName)"
onOK="#command('setDigitalPublisher', digitalPublisherBox = self)"
onSelect="#command('setDigitalPublisher', digitalPublisherBox = self)"
onChanging="#command('setupQuicksearchByEvent', searchlayout = event, prefix = 'PUB', tags = 'PublisherName, PublisherNameTranslit')"
mold="rounded" hflex="1" buttonVisible="false" autodrop="true">
<comboitem self="#{each=entry}" value="#{entry.key}" label="#{entry.value}"/>
</combobox>
And this is QuickSearch implementations:
#Command
public void setupQuicksearchByEvent(#BindingParam("searchlayout")Event event, #BindingParam("prefix") String prefix, #BindingParam("tags") String tags) throws WrongValueException, SearchException, IOException
{
if(event instanceof InputEvent)
{
InputEvent inputEvent = (InputEvent) event;
String inputText = inputEvent.getValue();
List<String> searchFields = Arrays.asList(tags.split(","));
ListModel model = new ListModelMap(ZKLogic.findDocsStartingWith(prefix, searchFields, "proxy", inputText), true);
ListModel subModel = ListModels.toListSubModel(model, Autocompleter.MAP_VALUE_CONTAINS_COMPARATOR, 10);
Combobox searchBox = (Combobox) event.getTarget();
searchBox.setModel(subModel);
searchBox.setItemRenderer(new ComboitemRenderer()
{
#Override
public void render( Comboitem item, Object data, int pos ) throws Exception
{
String publisherString = data.toString();
UID key = getUidFromPublisherString(publisherString);
int startIndex = publisherString.indexOf('=') + 1;
String publisher = publisherString.substring(startIndex);
item.setLabel(publisher);
item.setValue(key);
}
});
}
}
ZKLogic.findDocsStartingWith return map with UID-key and String-value.
With code above I achieved to get dropdown list when I switch to another window. I need to type something, then select another browser or notepad window - and comboitems will be displayed immediately.
So, my question still need answer, is there are any techniques to reproduce this windows switching in code? Or maybe I should do something with autocomplete, because I've got some ac working with preloaded lists, but this thing should return only 10 records from db, instead of all 70000 entries, every time when user type something in the field.
Edit 20/09/2013: Problem still exist. Rename question a bit, because thing that I need is to call render option by force in code. Is there is any way to do it? Code hasn't changed a lot, but print option in render method said, that method can miss two or more onChange events and suddenly render text for one variant.
Maybe you know another autocomplete options in zk framework where database participating? I'm ready to change implementation, if there is a guide with working implementation of it.
Ok I see two problems, you should solve first.
Setting the Renderer in every call of setupQuicksearchByEvent(...).
that is not logical, cos it is the same every time.
Add to the zul combobox tag something like
itemRenderer="#load(ivm.myRenderer)" ....
If you want just 10 items, do not let the db-request return more then 10.
If you use JPA klick here or for sql here or just google a bit.
After you fixed this two issues, we can exclude these as a reason of the unexpected behavior and fix it, if it is still present.
Edit
Ok, I have two possible ways to fix it.
Call Combobox#invalidate()
This schould force zk to rerender the Combobox, but could
lead to low performance and I would not prefer this.
Use Listbox with the select mold instead of Combobox.
To force the rerender, use Listbox#renderAll()
Try setting the selected item on your combobox or throw its related event
Solution is simple. Really. Nothing is better then brute-force, but I think I tried to avoid it and use it in despair.
#Command
public void setupQuicksearchByEvent(#BindingParam("searchlayout")Event event, #BindingParam("prefix") String prefix, #BindingParam("tags") String tags) throws WrongValueException, SearchException, IOException
{
if(event instanceof InputEvent)
{
InputEvent inputEvent = (InputEvent) event;
String inputText = inputEvent.getValue();
List<String> searchFields = Arrays.asList(tags.split(","));
Map<UID, String> publishers = ZKLogic.findDocsStartingWith(prefix, searchFields, "proxy", inputText);
Combobox searchBox = (Combobox) event.getTarget();
searchBox.getChildren().clear();
for (Map.Entry<UID, String > entry : publishers.entrySet())
{
Comboitem item = new Comboitem();
item.setLabel(entry.getValue());
item.setValue(entry.getKey());
searchBox.appendChild(item);
}
}
}
I am trying to allow my user to search through a table of information, dynamically hiding/showing results that contain the search. I have the hiding part down, and it works well, but I'm having trouble showing the table item again once the search criteria is changed.
Here is my hide code:
searchField.addModifyListener(new ModifyListener() {
#Override
public void modifyText(ModifyEvent arg0) {
modified = true;
for (int i = 0; i < table.getItems().length; i++) {
if (!(table.getItem(i).getText(2)
.contains(searchField.getText()))) {
table.getItem(i).dispose();
}
}
if ("".equals(searchField.getText())) {
modified = false;
//where I would want to un-hide items
}
}
});
Looking at your code, it seems you try to hide the item by calling dispose(). If you dispose a widget, it is gone for good. You cannot get it back.
If you want to unhide it again, will have to create a new item at the position of the previously hidden one with the same content.
Isn't it better to actually operate with some kind of a table model and JFace bindings, rather, then do it like that? And yes, disposing is not hiding. You should probably remove the item from the table.
You have probably to save the data from TableItem into collection before you call dispose. Then when you search again you could check that collection and if matches are found, then insert back into Table by creating new TableItem.