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.
Related
It might be that the way I'm approaching this just won't work, but to explain:
I have a DataTable with column sorting enabled via the default column header sorting graphic. In one of the column headers I also have a "select all" checkbox. The sorting and the "select all" both work, but I can't seem to prevent the sort operation from taking place when clicking on the select all checkbox.
The problem seems to be that the DataTables sort function is called ahead of the select all operation - in the capturing rather than bubbling up phase in what I understand to be the correct JS parlance.
I've been back and forward with this between different guides and forum posts, but am starting to wonder if it's going to work. I've added event.stopPropagation() to the select all routine, but because this is only called after the sort routine it seems of little use. I've also gone down the event.target route to conditionally only have the sort operation run if the clicked ID wasn't the checkbox, but for all I can tell the event object holds no reference to the original clicked element (does it?).
So, without editing the DataTables source (I'd really rather keep that off the shelf if at all possible), how do I have the sort routine run only when the column header itself is clicked, as opposed to a child element?
So I want something along the lines of:
function SelectAll(event)
{
event.stopPropagation(); //Doesn't help
...
}
$("#table_id").on("order.dt", function (event, settings)
{
if(event.not_clicked_select_all)
{
table_id.order();
}
});
How might this be done? Thanks.
Edit:
Jsfiddle
You can actually use a little css trickery with the z-index. Just put your inner div on a z-index that is higher than the cell.
th > div {
z-index:9998;
}
That will allow your checkbox (not the SELECT ALL label) to function the way you want it to. If you want to allow users to be able to click on the label too, then (if you are able) wrap the SELECT ALL in a label element and apply the same event.stopPropogation and my css technique to that label as well. Like this:
HTML
<th><div><input type='checkbox' id='select_all' onchange='SelectAll(event, "select_all", "include_")'><label for='select_all'> SELECT ALL</label></div><div>h</div></th>
CSS
th > div {
z-index:9998;
}
th > div > label {
z-index:9999;
}
Javscript
$("#select_all").click(function(event){event.stopPropagation()});
$("label[for='select_all']").click(function(event){event.stopPropagation()});
If you don't have access to the source and cannot wrap SELECT ALL inside a label element, there is probably some other css trick you can do. The key is to be able to target the label text individually and set it's z-index property.
Here is a working sample with both the checkbox AND the label:
https://jsfiddle.net/mspinks/y1g450ng/1/
When I have configured some block formats/styles which I then select from the Format dropdown, how can I remove/unselect/unapply them from my content so that the formatting is no longer applied to the given paragraph? Eg. I have <h5 class="something"> that I need to have removed from the paragraph in the content.
I have tried to make another entry in the dropdown which is defined as just [title: 'Regular'] (without any block, inline tags etc.) but selecting that doesn't do anything.
I also tried the Clear formatting button, but to my surprise that only removes the class, not the <h5> tag itself!
PS. I not talking about removing them from the dropdown menu, but how to remove them from the content in the editor.
Oh my goodness, is it really that simple. When you look at the dropdown you see a thick gray line on the left side for those formats that are applied to the current paragraph. And then you just choose the same format in the dropdown again - and it will be removed!
I have a dgrid with a permanently hidden column that needs to be there, because I need to filter the table on its values. I am using ColumnHider in order to hide it and it works fine.
However, using ColumnHider also shows the small "+" button in the table corner that is used to hide/show columns, and I really don't want that button to show (hiding/showing columns is not a functionality we need to offer). I know I can use the unhideable property on the column, but this simply removes them from the menu. Even if I set all columns as unhideable, the button is still there with an empty menu.
Apart from hiding it with CSS, which I did, is there a way to tell ColumnHider not to show that menu at all?
Thanks, regards.
There's no programmatic way to completely hide the ColumnHider menu. The simplest way is with CSS, e.g.:
.dgrid .dgrid-column-hider-toggle {
display: none;
}
It's also possible to just suppress a column from ColumnHider's list by adding unhidable: true to the column's definition.
However, it's not fully clear to me whether you even need the ColumnHider extension. Regardless of what's in your actual data, if you don't want a particular field to be displayed in the grid, just don't define a column for it in columns (or whichever property you're using, e.g. subRows or columnSets). You'll still have the full data item available to you e.g. for renderCell functions and if you extend renderRow.
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 div which I need to empty excluding a couple of divs inside it, the problem is, I have got it to work but the div's lose there jquery click functionality.
I have a stage which will have items dragged on them but I need to be able to empty these items but retain the click buttons which are also on the stage and stored in a div called keep.
I found this and it works but the things inside #keep still appear but they lose their jquery .click().
var $stage = $('#stage'), $noRemove = $stage.find('#keep');
$stage.html($noRemove);
This is because they are being removed and then re-added.
You either have to remove the children. OR Rebind the click method afterwards.
So for example:
$noRemove.click(function(...){});
See the Fiddle here : http://jsfiddle.net/r98dj/1/
Also, as a note. Make keep a class. Otherwise you'll end up with multiple divs with the same ID and this will cause you to fail W3C validation.