I have a script that restrict the click on a href link if there;s no checkbox selected. I want the editpr.php open in modal box. The problem is I'm not familiar with modalbox. Any help?
<a class="button edit" style="cursor:pointer;" ><span><b>Edit Purchase Request</b></span></a>
<a class="button remove" style="cursor:pointer;" name="remove"><span><b>Remove Purchase Request</b></span></a>
This is my script
jQuery(function ($) {
$('a.button.edit, a.button.remove').click(function () {
if ($('input[name="checkbox[]"]:checked').length == 0) {
return;
}
if (!confirm('Do you want to continue?')) {
return
}
var frm = document.myform;
if ($(this).hasClass('edit')) {
frm.action = 'editpr.php';
}
if ($(this).hasClass('remove')) {}
frm.submit();
})
})
You can't open a page in a modal box just with pure javascript, as "alert()" or "confirm()".
To do what you want you need to put your 'editpr.php' content inside a div, and make it modal with CSS.
Actually we have a lot of libraries that make it happen easily, I think that most used is: http://www.jacklmoore.com/colorbox/
Check the "Outside HTML (Ajax)" and "Outside Webpage (Iframe)" on this example page, probably is the same thing that you want to do: http://www.jacklmoore.com/colorbox/example1/
There are some useful jQuery plugins that can make your job really easy. I suggest you give them a try. Here you have an example.
Since you are already using jQuery you could use jquery-ui.
They have an exmple of what you want to do here:
http://jqueryui.com/dialog/#modal
Once you get your modal dialog element setup, all you have to do is make and XHR for editpr.php, load the result into the elements innerhtml, then display the dialog.
// setup your modal dialog
var el = $( "#editpr-dialog" ).dialog({
// ... (other config options)
modal: true
});
// XHR editpr.php and show the dialog box
$.get('editpr.php', function(data){
el.html(data).dialog('open');
});
The custombox plugin has a lot of beautiful features and works amazingly with Jquery: http://dixso.github.io/custombox/
Related
I have the follow simple code for a confirm box
<!DOCTYPE html>
<html>
<body>
<p>Click the button to alert the hostname of the current URL.</p>
<button onclick="myFunction()">Try it</button>
<script>
function myFunction() {
confirm("Confirm!!!!");
}
</script>
</body>
</html>
but my problem is I want with css to style the OK and Cancel button with a very simple way. I'm looking for a real simple solution.
This question has been asked more:
How to style default confirm box with only css?
confirm box styling
Answer; you can NOT style the confirm() function it's dialog box since it's browser generic.
You will have to search for alternatives like these:
jQuery Boxy: onehackoranother.com/projects/jquery/boxy/
jQuery Dialog: jqueryui.com/dialog/#modal-confirmation
You could also try to create your own dialog box. Which is not quite simple as you asked for. However, lot's of tutorials can be found:
Tutorial 1: www.developphp.com/view.php?tid=1385
Tutorial 2: tutorialzine.com/2010/12/better-confirm-box-jquery-css3/
(Sorry, as a beginner I'm not allowed to place more links)
alert and confirm are built-in to JavaScript and STOP page execution until they are answered, which is what allows you to do:
if( confirm('do you want to see this?') ) {
//show them.
}
Any confirm() solution that you work-up that can be styled won't be able to be included in an if statement. If you want code to only execute when the confirm is clicked, then you need to make that code as a callback, which make the above code look more like this:
mySpecialConfirm('do you want to see this?', function() {
//show them
} );
Then, you have to wire that function call into the "ok" button click on the confirm dialog that you create. This means that it's inherently more complicated just from a coding standpoint not to mention the code that has to wire that up to an HTML form. I would say that it's not worth it to re-invent the wheel and make your own modal. This means that you need to choose jQuery and jQuery UI, or jQuery and Bootstrap, or Dojo Toolkit, etc., and then from there look for the solution that they have for doing this, or use their modals.
As far as I know, you can't change the style of native pop up windows, but you can create your own with a bit of JavaScript trickery.
function promptWindow() {
// Create template
var box = document.createElement("div");
var cancel = document.createElement("button");
cancel.innerHTML = "Cancel";
cancel.onclick = function() { document.body.removeChild(this.parentNode) }
var text = document.createTextNode("Please enter a message!");
var input = document.createElement("textarea");
box.appendChild(text);
box.appendChild(input);
box.appendChild(cancel);
// Style box
box.style.position = "absolute";
box.style.width = "400px";
box.style.height = "300px";
// Center box.
box.style.left = (window.innerWidth / 2) -100;
box.style.top = "100px";
// Append box to body
document.body.appendChild(box);
}
After calling promptWindow you have your own pop up box, which you are free to style!
Hope this helped!
I am using bootstrap-popover to show a message beside an element.
If I want to show different text in the popover after the first time, the text does not change. Re instantiating the popover with new text does not overwrite.
See this js fiddle for a live example:
http://jsfiddle.net/RFzvp/1/
(The message in the alert and the message in the dom is inconsistent after the first click)
The documentation is a bit light on how to unbind: http://twitter.github.com/bootstrap/javascript.html#popovers
Am I using this wrong? The Any suggestions on how to work around?
Thanks
You can access the options directly using the jquery data closure dictionary like this:
$('a#test').data('bs.popover').options.content = 'new content';
This code should work fine even after first initializing the popover.
Hiya please see working demo here: http://jsfiddle.net/4g3Py/1/
I have made the changes to get your desired outcome. :)
I reckon you already know what you are doing but some example recommendations from my end as follows for sample: http://dl.dropbox.com/u/74874/test_scripts/popover/index.html# - sharing this link to give you idea for different link with different pop-over if you will see the source notice attribute data-content but what you wanted is working by the following changes.
Have a nice one and hope this helps. D'uh don't forget to up vote and accept the answer :)
Jquery Code
var i = 0;
$('a#test').click(function() {
i += 1;
$('a#test').popover({
trigger: 'manual',
placement: 'right',
content: function() {
var message = "Count is" + i;
return message;
}
});
$('a#test').popover("show");
});
HTML
<a id="test">Click me</a>
just in-case anyone's looking for a solution that doesn't involve re-instantiating the popover and just want to change the content html, have a look at this:
$('a#test').data('popover').$tip.find(".popover-content").html("<div>some new content yo</div>")
Update: At some point between this answer being written and Bootstrap 3.2.0 (I suspect at 3.0?) this changed a little, to:
$('a#test').data('bs.popover').tip().find ............
Old question, but since I notice that the no answer provides the correct way and this is a common question, I'd like to update it.
Use the $("a#test").popover("destroy");-method. Fiddle here.
This will destroy the old popover and enable you to connect a new one again the regular way.
Here's an example where you can click a button to set a new popover on an object that already has a popover attached. See fiddle for more detail.
$("button.setNewPopoverContent").on("click", function(e) {
e.preventDefault();
$(".popoverObject").popover("destroy").popover({
title: "New title"
content: "New content"
);
});
The question is more than one year old, but maybe this would be usefull for others.
If the content is only changed while the popover is hidden, the easiest way I've found is using a function and a bit of JS code.
Specifically, my HTML looks like:
<input id="test" data-toggle="popover"
data-placement="bottom" data-trigger="focus" />
<div id="popover-content" style="display: none">
<!-- Hidden div with the popover content -->
<p>This is the popover content</p>
</div>
Please note no data-content is specified. In JS, when the popover is created, a function is used for the content:
$('test').popover({
html: true,
content: function() { return $('#popover-content').html(); }
});
And now you can change anywhere the popover-content div and the popover will be updated the next time is shown:
$('#popover-content').html("<p>New content</p>");
I guess this idea will also work using plain text instead of HTML.
On Boostrap 4 it is just one line:
$("#your-element").attr("data-content", "your new popover content")
You can always directly modify the DOM:
$('a#test').next(".popover").find(".popover-content").html("Content");
For example, if you want a popover that will load some data from an API and display that in the popover's content on hover:
$("#myPopover").popover({
trigger: 'hover'
}).on('shown.bs.popover', function () {
var popover = $(this);
var contentEl = popover.next(".popover").find(".popover-content");
// Show spinner while waiting for data to be fetched
contentEl.html("<i class='fa fa-spinner fa-pulse fa-2x fa-fw'></i>");
var myParameter = popover.data('api-parameter');
$.getJSON("http://ipinfo.io/" + myParameter)
.done(function (data) {
var result = '';
if (data.org) {
result += data.org + '<br>';
}
if (data.city) {
result += data.city + ', ';
}
if (data.region) {
result += data.region + ' ';
}
if (data.country) {
result += data.country;
}
if (result == '') {
result = "No info found.";
}
contentEl.html(result);
}).fail(function (data) {
result = "No info found.";
contentEl.html(result);
});
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
Hover here for details on IP 151.101.1.69
This assumes that you trust the data supplied by the API. If not, you will need to escape the data returned to mitigate XSS attacks.
Learn't from previous answers
let popOverOptions = {
trigger: 'click',
...
};
// save popOver instance
let popOver = $(`#popover-unique-id`).popover(popOverOptions);
// get its data
let popOverData = popOver.data('bs.popover');
// load data dynamically (may be with AJAX call)
$(`#popover-unique-id`).on('shown.bs.popover', () => {
setTimeout(() => {
// set content, title etc...
popOverData.config.content = 'content/////////';
// updata the popup in realtime or else this will be shown next time opens
popOverData.setContent();
// Can add this if necessary for position correction:
popOver._popper.update();
}, 2000);
});
This way we can update popover content easily.
There's another way using destroy method.
http://jsfiddle.net/bj5ryvop/5/
Bootstrap 5.0 update
let popoverInstance = new bootstrap.Popover($('#element'));
And then:
popoverInstance._config.content = "Hello world";
popoverInstance.setContent();
(Caution: it will update popover content globally, so if you have multiple open popovers then they all will be updated with "Hello world")
I found Bootstrap popover content cannot changed dynamically which introduces the setContent function. My code (hopefully helpful to someone) is therefore:
(Noting that jquery data() isn't so good at setting as it is getting)
// Update basket
current = $('#basketPopover').data('content');
newbasket = current.replace(/\d+/i,parseInt(data));
$('#basketPopover').attr('data-content',newbasket);
$('#basketPopover').setContent();
$('#basketPopover').$tip.addClass(popover.options.placement);
if jQuery > 4.1 use
$("#popoverId").popover("dispose").popover({
title: "Your new title"
content: "Your new content"
);
Bootstrap 5.1
I tried about 8 different ways to change the content for my Bootstrap 5.1 project, but none worked. I could see the values in the underlying popover object and could change them, but they didn't show on the page.
I got it going by first using the Bootstrap Popover's selector option, which the docs don't explain that well, but basically amounts to putting a watch on the page, so if new popover elements are added to the page (with the selector) they will become popovers automatically.
$(function() {
// set up all popovers
new bootstrap.Popover(document.body, {selector: 'has-popover');
})
then in my ajax call where some different content has been fetched, I remove the existing popover div, change the attribute with the text, and add it again:
var $pop = $('#pop_id1234')
var html = $pop[0].outerHTML // save the HTML
$pop.remove()
var $new = $(html).attr('data-bs-content',popoverText) // data('bs-content') becomes bsContent which won't work
$('#pop-container').append($new)
How do you change the words on the buttons in a javascript alert? I am new so the simplest way possible would be greatly appreciated.
You can't.
Instead, you can create a fake dialog in the DOM, using jQuery UI Dialog.
not possible, the browser sets that
what you could do is make a fake alert from elements,
You can overriede window.alert and have your own implemenation of it.
window.alert = function(msg, options){
//Create the alert dialog box here using the default options and show the message.
}
You dont have to change your code in the application to use it.
Try something like this
function CustomAlert(msg){
var customAlert = $("#customAlert");
if(!customAlert.length){
customAlert = $(document.body).append('<div id="customAlert"><div class="message">Msg></div><div><input class="button" type="button" value="Ok" /></div></div>').hide();
}
customAlert.find("message").html(msg);
//Code to center the customAlert into view port along with faded background will go here
customAlert.find("input.button").unbind("click").click(function(){
//Hide the customAlert goes here
customAlert.hide();
});
}
In Rails 3, passing a :confirm parameter to link_to will populate the data-confirm attribute of the link. This will induce a JS alert() when the link is clicked.
I am using the rails jQuery UJS adapter (https://github.com/rails/jquery-ujs). The relevant code from rails.js is:
$('body').delegate('a[data-confirm], button[data-confirm], input[data-confirm]', 'click.rails', function () {
var el = $(this);
if (el.triggerAndReturn('confirm')) {
if (!confirm(el.attr('data-confirm'))) {
return false;
}
}
});
and
triggerAndReturn: function (name, data) {
var event = new $.Event(name);
this.trigger(event, data);
return event.result !== false;
}
I would like to know how this could be modified to instead yield a jQuery dialog (e.g. the jQuery UI Dialog) allowing the user to confirm or cancel.
My knowledge of JavaScript isn't sufficient to achieve this elegantly. My current approach would be to simply rewrite the $('body').delegate() function to instead instantiate a lightbox. However I imagine that there is a more effective approach than this.
As others have mentioned, you cannot use a jQuery dialog box, as $.rails.confirm needs to block until it returns the users answer.
However, you can overwrite $.rails.allowAction in your application.js file like this:
$.rails.allowAction = function(element) {
var message = element.data('confirm'),
answer = false, callback;
if (!message) { return true; }
if ($.rails.fire(element, 'confirm')) {
myCustomConfirmBox(message, function() {
callback = $.rails.fire(element,
'confirm:complete', [answer]);
if(callback) {
var oldAllowAction = $.rails.allowAction;
$.rails.allowAction = function() { return true; };
element.trigger('click');
$.rails.allowAction = oldAllowAction;
}
});
}
return false;
}
function myCustomConfirmBox(message, callback) {
// implement your own confirm box here
// call callback() if the user says yes
}
It works by returning false immediately, thus effectively canceling the click event. However, your custom function can then call the callback to actually follow the link/submit the form.
I just added an external API to the Rails jquery-ujs for exactly this kind of customization. You can now make rails.js use a custom confirm dialog by plugging into (and re-writing 1 line of) the $.rails.allowAction function.
See my article, Rails jQuery UJS: Now Interactive, for a full explanation with examples.
EDIT: As of this commit, I moved the confirm dialog function to the $.rails object, so that it can be modified or swapped out even more easily now. E.g.
$.rails.confirm = function(message) { return myConfirmDialog(message); };
I liked the answer from #Marc Schütz about overriding $.rails.allowAction the most of anything I found online - but I'm not a big fan of overriding the functionality in allowAction since it's used all throughout the jquery-ujs codebase (what if there are side effects? Or if the source for that method changes in a future update?).
By far, the best approach would be to make $.rails.confirm return a promise... But it doesn't look like that's going to happen anytime soon :(
So... I rolled my own method which I think is worth mentioning because it's lighter weight than the method outlined above. It doesn't hijack allowAction. Here it is:
# Nuke the default confirmation dialog. Always return true
# since we don't want it blocking our custom modal.
$.rails.confirm = (message) -> true
# Hook into any data-confirm elements and pop a custom modal
$(document).on 'confirm', '[data-confirm]', ->
if !$(this).data('confirmed')
myCustomModal 'Are you sure?', $(this).data('confirm'), =>
$(this).data('confirmed', true)
$(this).trigger('click.rails')
false
else
true
# myCustomModal is a function that takes (title, message, confirmCallback)
How does it work? Well, if you look at the source, you'll notice that the allowAction method halts if the confirm event returns a falsy value. So the flow is:
User clicks link or button with data-confirm attribute. There is no data-confirmed present on the link or button, so we fall into the first if block, trigger our custom modal and return false, thereby stopping the action from continuing in the ujs click handler.
User confirms in the custom modal, and the callback is triggered. We store state on the element via data('confirmed', true) and re-trigger the same event that was triggered previously (click.rails).
This time the confirm event will fall into the else block (since data('confirmed') is truthy) and return true, causing the allowAction block to evaluate to true.
I'm sure I'm even missing other ways that might make this even simpler, but I think this is a really flexible approach to get a custom confirm modal without breaking core jquery-ujs functionality.
(Also, because we're using .on() this will bind to any data-confirm elements on the page at load time or in the future, similarly to how .delegate() works, in case you are wondering.)
I don't understand why you need to use the jQuery dialog when the JavaScript confirm() function will still work just fine. I would do something like this:
$('a[data-confirm]').click(funciton() {
confirm($(this).data("confirm"));
});
If you want to use a dialog instead, it's a little different. You can one-off each dialog you want, or you can probably take a uniform approach application wide so that your rails.js or your application.js can handle any dialog instance. For example, you'd need something like this on your page:
<a class="dialogLauncher">The link that creates your dialog</a>
<div class="dialog" title="My confirmation title" style="display:none">
<p>My confirmation message</p>
</div>
Then, in your js:
$('.dialogLauncher').click(function() {
var dialog = $(this).next('.dialog');
dialog.dialog();
})
If you want to customize your dialog a little more, check out this example.
Edit
Now that I think of it, this would be a good opportunity for a custom form builder. You could override one of your Rails link tags to output html similar to what's listed above whenever a certain attribute is present, i.e. :dialog => true. Surely that would be the Railsy way to do it. You could add other options into your tag as well, like the dialog title, etc.
Edit
Better yet, instead of :dialog => true, use :confirm => "my confirm message" just as you would normally, but in your override of link_to, you will use the :confirm option to create the dialog html that jQuery needs, delete that option, and then call super.
This is how I got it to work. Please suggest any corrections / improvements
#
in rails.js
#
// Added new variable
var deleteConfirmed = false;
// Changed function to use jquery dialog instead of confirm
$('body').delegate('a[data-confirm], button[data-confirm], input[data-confirm]', 'click.rails', function () {
var el = $(this);
/*
if (el.triggerAndReturn('confirm')) {
if (!confirm(el.attr('data-confirm'))) {
return false;
}
}
*/
if (el.triggerAndReturn('confirm')) {
if(deleteConfirmed) {
deleteConfirmed = false;
return true;
}
$( "#dialog-confirm" ).dialog("option", "buttons",
{
"Delete": function() {
$( this ).dialog( "close" );
deleteConfirmed = true;
el.trigger('click');
return true;
},
Cancel: function() {
$( this ).dialog( "close" );
return false;
}
}
);
$( "#dialog-confirm" ).dialog("open");
return false;
}
});
#
in application.js
#
//Ensure confirm Dialog is pre-created
jQuery(function () {
$( "#dialog-confirm" ).dialog({
autoOpen: false,
resizable: false,
height:140,
modal: true
});
});
#
in layout.html
Alt you can place this div anywhere in your generated html
#
<div id='dialog-confirm' title='Confirm Delete'>
<p>
<span class='ui-icon-alert' style='float:left; margin:0 7px 20px 0;'>
This item will be permanently deleted. Are you sure?
</span>
</p>
</div>
This is how I solved this problem.
I tried a lot of different ways, but only this one works.
In rails.js
function myCustomConfirmBox(element, callback) {
const modalConfirmDestroy = document.getElementById('modal-confirm');
// wire up cancel
$("#modal-confirm #cancel-delete").click(function (e) {
e.preventDefault();
modalConfirmDestroy.classList.remove('modal--open');
});
// wire up OK button.
$("#modal-confirm #confirm-delete").click(function (e) {
e.preventDefault();
modalConfirmDestroy.classList.remove('modal--open');
callback(element, true);
});
// show the dialog.
modalConfirmDestroy.classList.add('modal--open');
}
In this place I used code of #Mark G. with some changes. Because this $(this).trigger('click.rails') snipped of the code didn't work for me.
$.rails.confirm = function(message) {return true};
$(document).on('confirm', '[data-confirm]', (event)=> {
if (!$(this).data('confirmed'))
{
myCustomConfirmBox($(this), (element, choice)=> {
element.data('confirmed', choice);
let clickedElement = document.getElementById(event.target.id);
clickedElement.click();
});
return false;
}
else
{
return true;
}
});
Then in the html.erb file I have this code for link:
<%= link_to "documents/#{document.id}", method: "delete", data: {confirm: "sure?"}, id: "document_#{document.id}" %>
and this code for modal:
<div id="modal-confirm" class="modal modal-confirm">
<h2 class="modal__ttl">Title</h2>
<div class="modal__inner">
<p>Description</p>
<div class="modal__btns">
<button type="button" name="cancel" id="cancel-delete" class="btn btn-primary">Cancel</button>
<button type="button" name="confirm" id="confirm-delete" class="btn delete_button btn-secondary">Delete</button>
</div>
</div>
</div>
I hope, it will help someone.
I'm using Colorbox to show the html content of hidden divs on my page. I can get this to work perfectly with the following:
$("a.colorbox").colorbox({width:"600px", inline:true, href:"#344"});
This will show the div with the ID of 344.
However, because I'm trying to build a scalable and dynamic page with WordPress, I want to be able to grab the ID of my divs through a function, rather than hard code them in the jquery call.
I modified Jack Moore's example:
$("a[rel='example']").colorbox({title: function(){
var url = $(this).attr('href');
return 'Open In New Window';
}});
so that it looks like this:
$(".colorbox").colorbox({width:"600px", inline:true, href:function(){
var elementID = $(this).attr('id');
return elementID;
}});
The problem with this is that the href property of the colorbox function is looking for a string with a # mark infront of the ID. I tried various ways of concatenating the # to the front of the function, including the # in the return value, and concatenating the # to the elementID variable. No luck.
I also tried using the syntax in Jack's example (with no luck) so that my return statement looked like this:
return "#'+elementID+'";
I think my basic question is: How do I use colorbox to show hidden divs on my page without hardcoding everything?
Thanks for your help,
Jiert
I didn't really like any of the answers given above. This is how I did it (similar but not quite the same).
I also fully commented it for people a bit new to Javascript and the colorbox plug in.
$(document).ready(function() { //waits until the DOM has finished loading
if ($('a.lightboxTrigger').length){ //checks to see if there is a lightbox trigger on the page
$('a.lightboxTrigger').each(function(){ //for every lightbox trigger on the page...
var url = $(this).attr("href"); // sets the link url as the target div of the lightbox
$(url).hide(); //hides the lightbox content div
$(this).colorbox({
inline:true, // so it knows that it's looking for an internal href
href:url, // tells it which content to show
width:"70%",
onOpen:function(){ //triggers a callback when the lightbox opens
$(url).show(); //when the lightbox opens, show the content div
},
onCleanup:function(){
$(url).hide(); //hides the content div when the lightbox closes
}
}).attr("href","javascript:void(0)"); //swaps the href out with a javascript:void(0) after it's saved the href to the url variable to stop the browser doing anything with the link other than launching the lightbox when clicked
//you could also use "return false" for the same effect but I proffered that way
})
}
});
And this is the html:
<a class="lightboxTrigger" href="#lightboxContent">Lightbox trigger</a>
<div id="lightboxContent" class="lightboxContent"> <!-- the class is just to make it easier to style with css if you have multiple lightboxes on the same page -->
<p>Lightbox content goes here</p>
</div>
I think it would work with multiple lightboxes on the one page but I haven't tested it with that.
I'm facing the same issue. What does your html look like? meaning, how did you structure your "divs"
Mine looks like this:
Javascript:
<script>
$(document).ready(function () {
$("a.colorbox").colorbox({ width: "50%", inline: true, href: function () {
var elementID = $(this).attr('id');
return "#" + elementID;
}
});
});
</script>
And the html looks like (I tried changing the display:none):
<a class='colorbox' href="#">Inline HTML</a>
<div style="display:none">
<div id="pop">
This data is to be displayed in colorbox
</div>
</div>
return "#" + elementID;
will have the desired effect as David says.
This is the way I got it to work
HTML: (taken from the example in one of the answers)
<a class="lightboxTrigger" href="#lightboxContent">Lightbox trigger</a>
<div id="lightboxContent" class="lightboxContent"> <!-- the class is just to make it easier to style with css if you have multiple lightboxes on the same page -->
<p>Lightbox content goes here</p>
</div>
Javascript:
$('a.lightboxTrigger').click(function(){
var ref = $(this).attr("href");
$.colorbox({ html: $(ref).html() });
$.colorbox.resize();
});