What this little script does is it creates a context menu (right click) that has two options, delete and edit. Ideally it would just ask to confirm to delete, because it is not the end of the world if you accidentally get taken to the modify screen. But in either case, I would like to create some kind of unique message to each situation to display to the user.
$("#myDiv").contextMenu({
menu: 'myMenu'
},
function(action, el, pos) {
var yesno = confirm(
'Are you sure?'
//you would like to delete?
//you would like to edit
);
if (yesno == true) {
window.location(action);
}
});
<div id="myDiv">
Right click for options.
</div>
<ul id="myMenu" class="contextMenu">
<li class="edit"> Edit </li>
<li class="delete"> Delete </li>
</ul>
I am not sure of what the accepted methodology would be in this case to grab some information about the actions, because the last thing I want is to write some super convoluted code when there is an easier way to do it.
This code seems moderately flexible, so I can add some more divs, or something like that. However, I would like to avoid a tag soup situation.
try using jQuery Alert plugin
http://abeautifulsite.net/blog/2008/12/jquery-alert-dialogs/
Related
I'm working on a site which will be maintained by not so tech savvy people, and I need to be able to give them the ability to add "see-more" anchors which use Jquery slide up/down to reveal their content.
My code works well for a single instance of the read more, but when there are multiple instances of this, it gets fairly screwed up.
javascript/jquery
$(".see-more").nextUntil(".see-less").wrapAll("<div class='see-more-content'></div>");
$(".see-less").hide();
var count= 1
/*
$(".see-more-content").each(function(){
var count= count+1;
$(this).data("count",count);
console.log(count);
});
*/
$(".see-more-content").slideUp(0);
$(".see-more").click(function(){
$(".see-more-content").slideToggle();
$(".see-more").hide();
$(".see-less").show();
});
$(".see-less").click(function(){
$(".see-more-content").slideToggle();
$(".see-less").hide();
$(".see-more").show();
});
HTML
<a class="see-more">See More...</a>
<ul>
<li>Advanced Elastic search Technology </li>
<li>Document Text Search</li>
<li>Embed Code Web Publishing for Images, Video & PDFs</li>
<li>Video Management with HTML5 Full</li>
<li>Previews On the Fly Conversions and Transcoding</li>
<li>Print on Demand</li>
<li>Stylized Collections (Lightboxes/Galleries)</li>
<li>Alerts and Notifications</li>
<li>Comments, Ratings and Favorites</li>
<li>WordPress and Drupal CMS Integrations</li>
<li>Dropbox Integration</li>
<li>Asset Level Performance Analytics • Site Activity Analytics Dashboard</li>
<li>Unlimited Custom User Access Levels</li>
<li>Integrated Content Contribution and Workflow</li>
<li>Personal Profile Management</li>
<li>Mobile App and Site </li>
<li>Watermarking</li>
<li>Rights Management</li>
<li>All New Feature Releases3</li>
</ul>
<a class="see-less">See Less...</a></div>
What I want to happen:
I want everything between the anchor with class see-more and anchor with class see-less, to get wrapped in a div, which when the anchor for see-more is clicked that div jquery slides down, when see-more is clicked, and slides up when see-less is clicked.
What is happening:
It works perfect when there is only one instance of see-more and see-less in a page. https://jsfiddle.net/TheWebTech/by3LsLuu/
When there are multiple instances of see-more and see-less in the html, the contents of all see-more+see-less blocks after the first instance are all moved/wrapped into the first block instances of the see-more see-less blocks get added.
https://jsfiddle.net/TheWebTech/by3LsLuu/4/
How do I prevent everything from being wrapped into the first instance of the see-more see-less block and instead have each one get wrapped separately?
Bonus but not really required: how can I make each see-more section slide up/down separately from eachother?
If you're going to keep the layout the same, you can use .prev() and .next() jQuery methods to determine which selector group you're referring too. Here's an updated fiddle with two instances:
https://jsfiddle.net/szva79d6/1/
First, I've made it so that your wrapping function applies to each selector individually, like so:
$(".see-more").each(function() {
$(this).nextUntil(".see-less")
.wrapAll("<div class='see-more-content'></div>");
});
What I've done in the two event methods is to make each event only act on the previous or next siblings, so that your events are properly delegated to each dynamically wrapped element.
$(".see-more").click(function() {
var $more = $(this),
$content = $more.next(".see-more-content"),
$less = $content.next(".see-less");
$content.slideToggle();
$more.hide();
$less.show();
});
$(".see-less").click(function() {
var $less = $(this),
$content = $less.prev(".see-more-content"),
$more = $content.prev(".see-more");
$content.slideToggle();
$less.hide();
$more.show();
});
You need to target specific to itself, try this:
$(".see-more").click(function(){
$(this).next(".see-more-content").slideToggle(); // find next content and show
$(this).hide(); // hide the see more button
$(this).nextAll('.see-less').first().show(); // show the next see less button
});
$(".see-less").click(function(){
$(this).prev(".see-more-content").slideToggle();
$(this).hide();
$(this).prevAll(".see-more").first().show();
});
Here's an updated fiddle
So, first some background.
I have 9 types of rooms that are displayed as thumbnails with the name. What I want to do is that on click "Additional Information" - the rooms with disappear and the expanded version of a chosen room type will appear with the description and bigger picture. Also, there is an ability to go next and previous in the expanded view. I do not have a problem with this expansion and previous/next. BUT!
Here is what I am trying to achieve: if the code looks approximately like
<ul id="room_holder">
<li><div class="room 1">Additional Info</div></li>
<li><div class="room 2">Additional Info</div></li>
and so on...
And the expandable area will look something like:
<div id="expandable">
<div id="picture">Blah-blah-blah, some description, etc</div>
</div>
So, basically, what I can't figure out is how to get the needed slide to show when the correspondint thumbnail is pressed. I know I can do the .addClass method, and copy the code 9 times, for each of the numbers (1-9). But I believe it is 9 times more compact if I have some sort of function, that gets the second class name (the number) by using .split(' ')[1] and then using it as part of the variable in the part which opens the corresponding expandable view. So, my question is: how do I do this? I am a newbie with javascript, but try to learn on the go!
Oh, and the codepen that I've been trying to deal with is:
http://codepen.io/godban/pen/QbZmxz
Firstly, you should use data-* attribute instead of classes (new in HTML5) data attributes, w3school :
<ul id="room_holder">
<li><div class="room" data-room="1">Additional Info</div></li>
<li><div class="room" data-room="2">Additional Info</div></li>
Then, use the click function from jQuery .click( handler ), use it this way to know which one has been clicked :
$(".room").click(function(event){
var target = event.currentTarget;
var room = $(target).data("room");
alert(room);
});
I have dropdown-Lists which have a lot of elements (>1000). When I select one of those elements the dropdown has to be rebuild because the selection of one element can cause others to disappear. I solve this in code behind (asp.net). Showing and hiding that dropdown usually is done in several milliseconds.
But when I select an element the div has to be rebuild which takes up to 20 seconds which is no surprise as that div contains about 300KB of Data which have to be sent to the client. The DIV looks like this:
<div id="ctl00_PlaceHolderMain_ctlProductSelector_SubstancesList" class="substancesListWrapper">
<ul>
<li class='elementSingle'>(2-Propyloxy)ethyl acetate</li>
<li class='elementSingle'>[(2-Propenyloxy)methyl] oxirane</li>
<li class='elementSingle'>1-(2-Pyridyl) piperazine</li>
<li class='elementSingle'>1,1,1,2-Tetrachloro-2,2-difluoroethane</li>
<li class='elementSingle'>1,1,1,2-Tetrafluoroethane</li>
<li class='elementSingle'>1,1,1-Trichloroethane</li>
(etc.)
Now I wonder if there is a way to compress that div-String and decompress it client-side by jQuery or something like that to reduce traffic. Does that work and if yes: What percentage of bytes do I usually safe?
This all happens in a SharePoint-Site (which should not make any difference hopefully)
You might improve several things.
One would be to move all your JavaScript links into one.
This would save you 85 characters per row.
<li class='elementSingle'>(2-Propyloxy)ethyl acetate</li>
<li class='elementSingle'>[(2-Propenyloxy)methyl] oxirane</li>
Could become this
<li class='elementSingle'><a href='#3268'>(2-Propyloxy)ethyl acetate</a></li>
<li class='elementSingle'><a href='#2415'>[(2-Propenyloxy)methyl] oxirane</a></li>
...
And one jquery click handler:
jQuery("li.elementSingle a").click(function(){
__doPostBack('ctl00_PlaceHolderMain_ctlProductSelector_pnlSubstances', this.href.replace('#',''));
});
Another point would be to remove class='elementSingle' and add a id to your ul for css/js.
This would save 22 characters per row.
If you're using jQuery already, just remove the anchors completely and provide id attributes for the list item elements.
The use a jQuery selector that reads out the id.
HTML would look kinda like this...
<div id="ctl00_PlaceHolderMain_ctlProductSelector_SubstancesList" class="substancesListWrapper">
<ul>
<li class='elementSingle' id="ct100-3268">(2-Propyloxy)ethyl acetate</li>
<li class='elementSingle' id="ct100-2415">[(2-Propenyloxy)methyl] oxirane</li>
etc...
The jQuery could be something like this...
$(function() {
$('#ctl00_PlaceHolderMain_ctlProductSelector_SubstancesList .elementSingle')
.click(function() {
var number = $(this).attr('id').match(/-(\d+)$/)[1];
__doPostBack('ctl00_PlaceHolderMain_ctlProductSelector_pnlSubstances', number);
});
});
(disclaimer; above is untested, but should give you a decent indication. Post a jsfiddle example first if you want a tested example).
Alternatively, think about using AJAX to load the list after loading the rest of the page.
I'm trying to code a navigation bar with four elements. If the element is currently selected it will have a "red" background image, if it is one of the other 3, it will have a "black" background image. my four tabs are 'timetable, homework, notifications and sport'
I tried making 8 functions like the 2 below
function setTimeRed()
{
document.getElementById("time").style.ClassName = 'timetable_r';
}
function setTimeBlack()
{
document.getElementById("time").style.ClassName = 'time_r';
}
And then four blocks like this:
function changeTimeButton()
{
var timePath = new String();
timePath = document.getElementById("timetable").style.backgroundImage;
if(timePath == "url(assets/img/tabs/time_black.png)" || timePath == "")
{
setTimeRed();
setHomeBlack();
setNotiBlack();
setSportBlack();
}
else {
}
}
finally, my html has this:
<div id="tabbar">
<ul id="tabs">
<a href"#" onclick="changeTimeButton()">
<li id="timetable" class="time_b">
<p>Timetable</p>
</li>
</a>
<a href"#" onclick="changeHomeButton()">
<li id="homework" class="home_b">
<p>Homework</p>
</li>
</a>
<a href"#" onclick="changeNotiButton()">
<li id="notifications" class="noti_b">
<p>Notifications</p>
</li>
</a>
<a href"#" onclick="changeSportButton()">
<li id="sport" class="sport_b">
<p>Sport</p>
</li>
</a>
</ul>
</div>
It works once then does nothing. Why?
I think error is in your script, just one example
document.getElementById("time").style.ClassName = 'timetable_r';
which should be (there are no elements with id "time" in your html, at least in the code you posted here)
document.getElementById("timetable").style.ClassName = 'timetable_r';
Another thing, if it works once, then seems it might save some issues with new session or existing session. I am not an expert on javascript. But if it helps, please inform.
When turning the background color off, you need to remove any existing classes like this:
document.getElementById("timetable").className =
document.getElementById("timetable").className.replace
( /(?:^|\s)time_b(?!\S)/ , '' )
Since you're using classes instead of modifying the styles in the javascript, you should stick to that. You seem to be trying to set the background image in the javascript.
Instead, you should apply that background image to the class' styles in the CSS.
Using a framework like jQuery would make this much easier since it has helper functions such as addClass(), toggleClass(), and removeClass(). You should also set the 'a' tags inside the 'li'. It makes for cleaner code in my opinion. The browser will still read the click and be able to apply the classes correctly.
Also, you shouldn't have to repeat yourself so often in your code. One solution is to create a generic function and pass the element's id in as a parameter. Then, you use an 'active' class instead of 'timetable_r'. The active class will be applied to the active link and you won't have to write the functions out so many times. Hope this helps.
I've got the following HTML code, which essentially pertains to a post where I announce something in just a few lines, end it with "[...]", and add a "Read more" link-button at the bottom. When this button is clicked, additional content that's hidden will fadeIn as the button disappears, leaving visible the introductory text and the one that was hidden -- simple enough. Now, I've already written the code for this, but the complication comes when I try to also remove that "[...]" (from the post where the click button happened) that I included in the sneak peek. Here's the HTML:
<div class="entry">
<p>Welcome. Talk about something briefly and click below for more. [...]</p>
<div class="slide-content">
<p>Hidden content.</p>
</div>
<span id="revealer" class="button">Read more</span>
</div>
Classes "entry" and "button" belong to my CSS file, while "slide-content" belongs to my .js file to control the fadeIn effect. The ID "revealer" also belongs to the .js file for the same purpose. This HTML is wrapped in a div tag with a class of "box". This is the format that each post follows, exactly the same format with the same HTML elements -- every time an announcement needs to be made, it's just a matter of putting the content between the paragraph tags and publish. Here is where my problem comes in, since I can't find a way to remove the "[...]" only in the post where the button has been clicked. I tried doing the following but it resulted in the deletion of all "[...]" throughout multiple posts:
$('.entry p').each(function() {
var textReplace = $(this).text();
$(this).text(textReplace.replace('[...]', ''));
});
Summary:
I need to remove the "[...]" text only from the post where the user has clicked on (the "Read more" button). The idea is to have this removed while at the same time the hidden content fades in.
I've been able to accomplish the above but for all instances of "[...]". I need to sophisticate my selection by modifying my jQuery code or the HTML.
Option 3 is to get rid of this "[...]", but I would like to leave it there to let the user know she has more content to read, and I would like to have that "Read more" button in all posts for consistency.
~Thanks in advance!
First, you mention you have multiple of these. In that case, this:
<span id="revealer" class="button">Read more</span>
will not work. id attribute has to be unique per document, i.e. you can have at most one element with the specific id value.
If you make your HTML (for each of the blocks) like this:
<div class="entry">
<p>Welcome. Talk about something briefly and click below for more. [...]</p>
<div class="slide-content">
<p>Hidden content.</p>
</div>
<span class="revealer button">Read more</span>
</div>
and your JS like this:
function replace(fromp) {
var textReplace = fromp.text();
fromp.text(textReplace.replace('[...]', ''));
}
$('.revealer').click(function() {
var fromp = $(this).siblings().eq(0);
replace(fromp);
});
it will work properly. Working example:
http://jsfiddle.net/G4t7Q/
Hope this helps.
When you run your page initialization script, you could use jquery to select all of the posts and all of the remove buttons and link them up via their click event. I've created a JSFiddle example, but here's the jist of it:
var removers = $(".remover")
var posts = $(".post")
for (var i = 0; i < removers.length; i++) {
$(removers[i]).click( { post: posts[i] },
function(event) {
var textReplace = $(event.data.post).text()
$(event.data.post).text(textReplace.replace('[...]', ''))
}
)
}
This is a simplified example; it assumes the posts and buttons are sorted in the markup.