I'm using Django and Zurb-foundation.
On a certain page I have on the one hand a bunch of items organized in a table, displaying their properties. On the other hand, on the same page I have a form which contains a select box, the elements in which are the previously mentioned items. Now in principle as the number of items grows larger it will get boring finding one in the form's select box. I would like to, if you click on one of those items being displayed on the table, have that same item be selected in the select box.
How do I do this? I know absolutely nothing about javascript, but if you can at least mention the relevant key concepts, I'll learn them.
Thanks!
Please check out this JSFiddle: http://jsfiddle.net/zvCvL/5/
Although I have left several comments detailing how this should be done, I will summarize below:
Loop through each of the items and their descriptions using Django's templating engine's looping feature (this part is going to be left up to you to figure out, but I have left you a link in the fiddle to get you started) For example, you will be adding these to your tbody in each of your loops:
<!-- loop iteration one -->
<tr>
<td class="item1">Item 1</td>
<td class="item1">The first item</td>
</tr>
Do not forget, however, that my method requires that a unique name be given to the td's in every iteration.
Then, you can work on the dropdown. This will require a simplier loop, just adding these to the ul which acts as your dropdown:
<!-- loop iteration one -->
<li class="item1"><a>Item 1</a></li>
Once again, this requires a unique class name, yet one that corresponds to the class name given to the item in table.
Finally, you have your JavaScript to take care of. Simply, you can check to see if the user is hovering over an li, check which class it belongs to, and apply some sort of color to all elements which have that same class. Of course, one caveat is that this will act upon all list elements. I'll leave it up to you to change that as needed.
Hopefully this helps! (The ultimate result is: http://jsfiddle.net/zvCvL/5/embedded/result/)
Related
SUMMARY: I have a column for ids within an ag-grid table. How can I get a button-click to only display some of the rows (for which I have a list of ids), while not re-writing the whole table?
BACKGROUND: I am using the community version of ag-grid and am using it with Javascript. I have a column with the id numbers in it. When I click a button (or something else eventually, but start with a button for simplicity), is it possible for it to act as a filter within the table, and hence could be undone by clicking another button to clear the filter?
In case that wasn't cleaar, I am looking to do:
1. Click button1
2. Display certain rows within a table whose id numbers are in my list variable
3. Have this button1's action act as a filter that can be undone by a button2 (which could be programmed perhaps like a clear filter button)
Is this possible to do with a quickfilter? Otherwise, if this isn't possible, how could I do this when over-writing the table, whilst still having the option to 'instantly' revert back to the original table
(I don't think I need to add code as I am unsure of how to build in this functionality)
Thanks in advance.
I have a table with variable number of records (could be up to hundreds) where its body is build with one ng-repeat.
Within each record, there are two input fields of type select where their contents is also built using ng-repear and the number of options for each is about 100.
This is working right now, except that it takes a lot of time for the page to be built (several seconds; I guess due to the large number of html records that AngularJS is adding to the DOM).
Here is an example of one of the selects:
<select class="form-control" ng-model="One_Source.Measuring_Method_Code">
<option ng-selected="{{One_Method.Value == One_Source.Measuring_Method_Code}}"
ng-repeat="One_Method in All_Collections.Parameters_Test_Methods"
value="{{One_Method.Value}}"
title="{{One_Method.Test_Method_Name}} | {{One_Method.Method_Internal_Name}}">
{{One_Method.Value}}
</option>
</select>
Two questions:
Is there a simple way to speed up the page building process?
As shown in the example, each option in the list has a title clause displaying a detailed description of the option's meaning. How can I add a title to the select showing the description of the current value?
For the first question I was thinking about building the list of options for each select element only upon clicking on it, but I'm not sure if that would be the best way to do it.
Try using one time bindings so that Angular doesn't watch the value by prefixing it with ::. It can also be more efficient to use track by in your ng-repeat if each row has a unique value, like an ID.
<option
ng-selected="{{One_Method.Value == One_Source.Measuring_Method_Code}}"
ng-repeat="One_Method in All_Collections.Parameters_Test_Methods track by One_Method.id"
value="{{::One_Method.Value}}"
title="{{::One_Method.Test_Method_Name}} | {{::One_Method.Method_Internal_Name}}"
>
{{::One_Method.Value}}
</option>
If you still can't gain the performance you're expecting from #doublesharps's answer, you will have to implement one of the following:
You could build a custom list that has a 'load more' button which would destroy say the first '50' options and load the next 50.
A better option would be to turn this into an autocomplete, where the user searches for values.
Virtual repeat - Something angular material does really well, it constantly draw's and re-draws new elements based on the scroll position inside the element.
Other resources:
http://blog.scalyr.com/2013/10/angularjs-1200ms-to-35ms/
https://github.com/stackfull/angular-virtual-scroll
http://klajd.github.io/angular-virtual-repeat/#/Home
I found a PARTIAL SOLUTION that still needs to be polished but is quite promising.
During creation of the page, I do not make use of ng-repeat for the options but instead deploy a single option with the value received for the field from the database (if any, otherwise the select element is left blank).
When the user clicks on the select element a $scope function is invoked that checks the number of options within the select element and, if less or equal to 1, the inner HTML of this select element is re-generated and deployed.
Though clicking on all these select in the page will take (accumulative) a comparable time as when built upon load, this time is distributed over several events (the user clicking on all the select elements) and hence it is not perceived by the user.
Now, by polishing I mean that there is a strange behavior. In order to see the generated list of options, I need to click on the select twice. Will keep investigating this and post the solution (hoping I find one).
I have form and list of objects at the same page. When I insert a new row, it is not very easy to see where the newly inserted row is placed. Therefore, I thought I could color/highlight the newly inserted row (and perhaps remove the highlight after a few seconds).
How can I do this? I think a way to do this could be using a method on the server which returns the inserted id (return Collection.insert(doc);) and on the client use a callback with
Meteor.call('insertDoc', function(err,result) {
// do something with result
});
I think I can use a reactive-var to save the id of the last inserted row and in the loop highlight the row with
{{#each docs}}
<li class="{{isActive}}">{{name}}</li>
{{/each}}
and have a helper to return active if this._id equals the reactive var with the last inserted id.
But is this the best way to do it? How can I remove the color after some seconds? I have seen such behaviour on many pages but I cannot find any tutorials/code snippets to achieve this.
I wrote a package that uses Meteor's UI hooks to fade items in and out of a list as they are added and removed, to help users maintain context as data changes:
https://github.com/mizzao/meteor-animated-each
There is a demo at http://animated-each.meteor.com/. You can see that as items are added and removed, they are faded in and out. If items are inserted off the screen, the visible area does not scroll.
This isn't doing exactly what you want, but you can use the same idea to highlight items as they appear as well, as opposed to the simple fade in.
Note that all of this happens at the UI rendering level - not the template/code level. The UI hooks are also not well documented right now, but they've been around for a while.
I don't know if your method is the best, but that's how I'd go about doing it.
As for the animation, I'd use a CSS3 animation. Plenty to choose from ( https://developer.mozilla.org/en-US/docs/Web/CSS/animation ), and you can easily make them fade to the standard color. The animation would also only be applied to the last inserted item (because of the way you did it, only the last item would have the "active" class)
I have a very large html table that is similar to the following:
<table>
<tr>
<td>value1</td>
<td>value2</td>
</tr>
<tr>
<td>value3</td>
<td>value4</td>
</tr>
</table>
For each value I need to have a dropdown, where a user can click to change the value. This would trigger an ajax function. What would be the best way to do this? A dropdown in each ? One dropdown that changes position? How should i go about adding this?
This solution changes the cell to a dropdown when clicked, and back to a cell when a value is selected, just in case this was desired effect.
Something similar to this, I would assume. :) I used jQuery. :)
$("tr").each(function(){
$("td").each(function(){
var before = $(this).text();
$(this).html("<select><option>"+before+"</option></select>");
});
});
jsFiddle Example
Some of this depends on the experience you want for the user, but I would lean towards putting a select element in each table cell. You can then have the select hidden until the user selects one of the values to change, or you can have the select elements visible the entire time. This is easier because you can put the values into the select box before the browser renders the page. If this is not usable, for example, if the browser has trouble rendering the page because of the size of the markup, then you could move to using a single select element.
If you use a single select box, that would require you to move it around to the correct cell, and also determine how to get the possible values into the select box. You could use a data attribute on your td tags to store the data, or you could make an ajax call. But that could be chatty if you go back to the server each time a cell needs to be edited. Basically this would be the harder option to get right.
Start with the simple way (select in each td). And if that proves to be problematic, move on to the harder one. That is what I would do.
Alright, I got it working. This is an alternative to my other answer.
This gets each tr to be a dropdown and the tds are the options. I used jQuery.
$("tr").each(function(i){
$("td").each(function(){
$(this).replaceWith("<option>"+$(this).text()+"</option>");
});
$(this).replaceWith("<select>"+$(this).html()+"</select>");
});
Updated jsFiddle Example
This is the problem page I'm developing.
Consider the leftmost column header, with header text "Undr." Here is the simplified html for that column header:
<th class="underlying" onclick="toggleColSelect(this);">
<img class='ad' onclick="toggleColSortOrder(this);">
Undr
</th>
The user can do two things in the column header:
select and deselect the column, by clicking the column header. EDIT: The column is selected when the column header has a yellow background; and unselected when the column header has a white background.
select ascending or descending sort on the column contents, by clicking the up/down-arrow image.
However, clicking the image also selects/deselects the column, which I don't want. When he clicks the image, I want to toggle the sort order only; I don't want to toggle the select on the column.
My JavaScript function toggleColSortOrder(); does indeed toggle only the sort order; but it seems the function to select the column also gets called (wrongly) when the user clicks the image.
What I've tried: thinking this might somehow be a manifestation of bubble-up at work, I tried all combinations of returning true, false and nothing in each of the two functions. None of this had any effect. I'd like to avoid hacking the JavaScript any further.
Question: how, by changing my html or css, can I prevent the function toggleColSelect(); being called when the user clicks inside the up/down-arrow image?
Your can cancel event-bubbling by adding
event.cancelBubble = true;
to your functions. See this fiddle: http://jsfiddle.net/fcyCz/
Here is my theory, since your <img> tag is INSIDE your <th> tag, you cannot click the <img> without first 'clicking' through the <th>. If there was a way to un-nest these two tags, I would then assume that their functions would be called separately. Possibly using a <div> to align your <img> over the correct spot. I am going to try to do live adjusting of what I just said using firebug and see (if it doesnt break the javascript) if it works, and I will report back.
Good luck.
As Tomalak points out, the click event for the <img> is bubbling up to the parent <th>, and so you must specify otherwise in your function. Also, add a call to event.stopPropagation() for the browsers which have deprecated cancelBubble.