As you probably know, any action inside twitter's bootstrap leads to the closing of the dropdown except when using :
$('.dropdown-menu').click(function(event){
event.stopPropagation();
})
Unfortunately, event.stopPropagation() stops the ajax query as well.
what I want to achieve is something like when you get a friend request on FB and you accept/decline inside the dropdown without it being closed.
Can you help me ?
Just put the ajax call after the event.stopPropagation call.
In this case, the click should be on $('.dropdown-menu > li > a') element. See example below.
/**** Ignore this command - just used to mock up an ajax response **/
$.mockjax({
url: '/likethis',
responseTime: 1000,
responseText: {
status: 'success',
fbStatus: 'liked'
}
});
$('.dropdown-menu > li > a').click(function(event){
event.stopPropagation();
$.ajax({ url: '/likethis',
success: function() {
$('#likelink').html('<span class="glyphicon glyphicon-ok"></span> Liked!');
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery-mockjax/1.5.3/jquery.mockjax.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet"/>
<!-- Single button -->
<div class="btn-group">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
Like This <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li>Like</li>
</ul>
</div>
Related
I'm hitting some trouble in trying to change the text in a button after a user clicks on the wishlist link. The Ajax call is working successfully right now and the data is updated correctly in the DB, currently the function displays a notification pop up in the browser when a user clicks on wishlist, but I would like to change the "wishlist" part of the button to "Added to wishlist" after a successful submission.
EDIT:
I have added $("#btn span").text("Added to wishlist");
But it's still not working.
function wish($p_id){
var w_id = $p_id;
var email = $(".wish").data("user");
if(email != 0){
$.ajax({
url:"function.php",
method:"post",
data:{w_id:w_id,email:email},
success: function($wish){
if($wish > 0){
notif({
msg:"Product Already Added to wishlist!!!",
type:"warning",
width:330,
height:40,
timeout:1000,
})
}else{
$("#btn span").text("Added to wishlist");
notif({
msg:"Added to wishlist",
type:"success",
width:330,
height:40,
timeout:1000,
})
}
}
})
}
}
and the HTML part
<a href='$add_wish' id="btn"class='btn btn-default add-to-cart wish' data-user='$s_email' onclick='wish($id)'>
<i class='glyphicon glyphicon-heart'></i> Wishlist
</a>
The issue is that in this code:
$("#btn span").text("Added to wishlist");
your selector is missing the target. It tries to find an element with the ID of "btn", which is fine, but then it tries to look for a <span> element inside that, which doesn't exist.
It's trivial to resolve of course by wrapping the text in the expected <span>:
$("#btn span").text("Added to wishlist");
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a href='$add_wish' id="btn"class='btn btn-default add-to-cart wish' data-user='$s_email' onclick='wish($id)'>
<i class='glyphicon glyphicon-heart'></i>
<span>Wishlist</span>
</a>
N.B. Note that writing simply
$("#btn").text("Added to wishlist")
is undesirable because it will erase the <i> containing the icon.
Demo (for comparison with above):
$("#btn").text("Added to wishlist");
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a href='$add_wish' id="btn"class='btn btn-default add-to-cart wish' data-user='$s_email' onclick='wish($id)'>
<i class='glyphicon glyphicon-heart'></i>
Wishlist
</a>
Relevant documentation: https://api.jquery.com/category/selectors/
Identify your button by adding an id and put your text inside a span
<a href='$add_wish' id='my_button' class='btn btn-default add-to-cart wish' data-user='$s_email' onclick='wish($id)'>
<i class='glyphicon glyphicon-heart'></i> <span>Wishlist</span>
</a>
You have to change the innerText of the span, just add the following code after the product is added :
document.querySelector('#my_button span').innerText = 'Added to wishlist';
I have a bootstrap 4 popover with list inside which comes from a viewcomponent element (asp net core 3.1 project).
This popover is inside layout navigation bar (not sure if that's relevant) and after hovering over it the list should appear.
Now every list element appears correctly but after I click any of the list elements I want to send ajax post request but I cannot make my javascript work. I am not sure what is the problem. Is it because my script is only loaded when I hover on popover? Am I using events incorrectly? I tried a lot of variations to test if JS is working and seems like everything failed.
ViewComponent:
#model mymodel;
<div class='list-group'>
#foreach (var item in Model.Item)
{
<a href='#item.Url' class='btn list-group-item list-group-item-action mb-1'>You have been invited to join event: <b>#item.Name</b></a>
}
#foreach (var item in Model.AnotherItem)
{
<a id='lmao' href='#' onclick='doSomething(#item.Id);' class='list-group-item list-group-item-action mb-1'>You have been invited to join team: <b>#item.Name</b></a>
}
</div>
<script>
$('#lmao').click(function () { MyFunction(); return false; });
function MyFunction() {
alert('hello');
console.log(data);
console.log(this);
}
</script>
_Layout Page with popover:
<div class="navbar-collapse">
<ul class="navbar-nav">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" data-toggle="dropdown">
Settings
</a>
...
<a tabindex="0" class="dropdown-item pop" data-container="body" data-html="true" title="Your invitations" data-toggle="popover" data-placement="left" data-content="#await Component.InvokeAsync("InvitationList")" style="cursor: pointer;">Invitations (number coming from another viewcomponent)</a>
...
</div>
</li>
...
Popover JS in Layout:
<script>
$('.pop').popover({
trigger: 'manual',
html: true
})
.on('mouseenter', function () {
var _this = this;
$(this).popover('show');
$('.popover').on('mouseleave', function () {
$(_this).popover('hide');
});
}).on('mouseleave', function () {
var _this = this;
setTimeout(function () {
if (!$('.popover:hover').length) {
$(_this).popover('hide');
}
}, 300);
});
</script>
My popover works correctly, I see the items loaded from viewcomponent, I can press on each of them and go to preset href.
What doesn't work is javascript coming from viewcomponent or atleast I am failing to test it. My end goal is to make a post call if any of the items in the popover are clicked.
I tested your codes and found if you directly call viewcomponent in data-content, the jacascripts in ViewComponent will be recongnized as html, so it will never be called. Instead, you can define an area for viewcomponent separately
<a id="invitations" tabindex="0" class="dropdown-item pop" data-container="body" data-html="true" title="Your invitations" data-toggle="popover" data-placement="left" style="cursor: pointer;" data-content="">invitations</a>
<div id="vc" style="display:none">
#await Component.InvokeAsync("InvitationList")
</div>
Use js to append it to data-content
$("#invitations").attr("data-content", $("#vc").html())
Since it is a new element from other page, the handler won't be bound on that new element, your click function should be like this:
<script>
$('body').on('click', '#lmao', function () { MyFunction(); return false; });
function MyFunction() {
alert('hello');
console.log(data);
console.log(this);
}
</script>
Test result:
I have a simple form
HTML
<form action="#Url.Action("Controler", "FES")" method="POST">
<button name="upload" type="submit" id="upload-fes-btn-control" class="btn btn-danger">Contrôler</button>
</form>
The request time when submitting may sometimes be long (more than 30s, bc of business logic on big file...)
I want to change the value of the button after user has clicked on it. The objective is to display a font-awesome loader instead of the initial text (<i class="fas fa-spinner fa-pulse"></i>). There is the jQuery snippet I use to achieve this...
jQuery
$("#upload-fes-btn-control").click(function () {
$(this).attr('value', '<i class="fas fa-spinner fa-pulse"></i>');
});
I'm facing an error due to this code in my Controller
A potentially dangerous Request.Form value was detected from the client
Controller
if (Request.Form["upload"] != null)
{
//Logic with ViewModel...
}
How can I change the text displayed in the button from text to fa image loader without throwing that error ?
use this code $(this).html('<i class="fa fa-spinner fa-pulse"></i>');
$("#upload-fes-btn-control").click(function (e) {
e.preventDefault();
$(this).html('<i class="fa fa-spinner fa-pulse"></i>');
//example after page load
setTimeout(function(){
$("#upload-fes-btn-control").html('');
$("#upload-fes-btn-control").html('Contrôler');
}, 5000);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<form action="#Url.Action("Controler", "FES")" method="POST">
<button name="upload" type="submit" id="upload-fes-btn-control" class="btn btn-danger">Contrôler</button>
</form>
I am working on a bootsrap3 template, which is Ajax based.
My index file has a leftside menu and a conent block middle of the page, every time I click on a subelement of this left menu, an Ajax laod will put the page content in this block(ajax-content).*
Any time I call any page, my URL normally looks something like this /index.php#page-one.php, except when the page contains form submission.
The Problem happens when I add an action attribute (acion="page-one.php") to my form tag.
After the form submission my URL turns to /page-one.php ;
consequently I get a white page containing the page-one.php elements whitout any CSS styling and of course no index-file's elements.
What is the correct and best way to come a cross this issue?
index.php:
<body>
<!--Start Container-->
<div id="main" class="container-fluid">
<div class="row">
<div id="sidebar-left" class="col-xs-2 col-sm-2">
<ul class="nav main-menu">
<li class="dropdown">
<a id="configuration" href="#" class="dropdown-toggle">
<i class="fa fa-gears"></i>
<span class="hidden-xs">Menu-element</span>
</a>
<ul class="dropdown-menu">
<li><a class="ajax-link" href="page-one.php">Menu-Subelement-one</a></li>
<li><a class="ajax-link" href="page-wo.php">Menu-Subelement-two</a></li>
</ul>
</li>
</ul> <!-- end of main-menu-->
</div>
<!--Start Content-->
<div id="content" class="col-xs-12 col-sm-10">
<div class="preloader">
<img src="img.gif" class="loader" alt="preloader"/>
</div>
<!--inside this div a short description/introduction(simple text inside a <p> tag) about the Menu-element will be shown-->
<div id="content-header"></div>
<!--inside this div the page content of the Menu-subelement will be shown-->
<div id="ajax-content"></div>
</div>
<!--End Content-->
</div>
</div>
<!--End Container-->
<script src="plugins/jquery/jquery-2.1.0.min.js"></script>
<script src="plugins/jquery-ui/jquery-ui.min.js"></script>
<script src="plugin/jquery.form.js"></script>
<script src="js/script.js"></script>
And here is my script.js:
//
// Function for load content from url and put in $('.ajax-content') block
//
function LoadAjaxContent(url){
$('.preloader').show();
$.ajax({
mimeType: 'text/html; charset=utf-8', // ! Need set mimeType only when run from local file
url: url,
type: 'GET',
success: function(data) {
$('#ajax-content').html(data);
$('.preloader').hide();
},
error: function (jqXHR, textStatus, errorThrown) {
alert(errorThrown);
},
dataType: "html",
async: false
});
}
//////////////////////////////////////////////////////
document.ready
//////////////////////////////////////////////////////
$(document).ready(function () {
var ajax_url = location.hash.replace(/^#/, '');
if (ajax_url.length < 1) {
ajax_url = 'home.php';
}
LoadAjaxContent(ajax_url);
$('.main-menu').on('click', 'a', function (e) {
var parents = $(this).parents('li');
var li = $(this).closest('li.dropdown');
var another_items = $('.main-menu li').not(parents);
another_items.find('a').removeClass('active');
another_items.find('a').removeClass('active-parent');
if ($(this).hasClass('dropdown-toggle') || $(this).closest('li').find('ul').length == 0) {
$(this).addClass('active-parent');
var current = $(this).next();
if (current.is(':visible')) {
li.find("ul.dropdown-menu").slideUp('fast');
li.find("ul.dropdown-menu a").removeClass('active')
}
else {
another_items.find("ul.dropdown-menu").slideUp('fast');
current.slideDown('fast');
}
}
else {
if (li.find('a.dropdown-toggle').hasClass('active-parent')) {
var pre = $(this).closest('ul.dropdown-menu');
pre.find("li.dropdown").not($(this).closest('li')).find('ul.dropdown-menu').slideUp('fast');
}
}
if ($(this).hasClass('active') == false) {
$(this).parents("ul.dropdown-menu").find('a').removeClass('active');
$(this).addClass('active')
}
if ($(this).hasClass('ajax-link')) {
e.preventDefault();
if ($(this).hasClass('add-full')) {
$('#content').addClass('full-content');
}
else {
$('#content').removeClass('full-content');
}
var url = $(this).attr('href');
window.location.hash = url;
LoadAjaxContent(url);
}
if ($(this).attr('href') == '#') {
e.preventDefault();
}
});
$('#formSubmit').ajaxForm();
});
page-one.php:
<!--some php code here-->
<form class="validateForm" id="formSubmit" action="page-one.php" method="get">
<div class="form-group">
<label>Username</label>
<input type="text" class="form-control" name="username" />
</div>
<div class="form-group">
<div class="col-sm-offset-5 col-sm-8">
<button type="submit" class="btn btn-primary btn-label-left">
<span><i class="fa fa-save"></i> Save</span>
</button>
</div>
</div>
</form>
Thanks!
I had the same issue to solve for the intranet I work on.
For me, the good way to do this is to avoid using submit method and use instead an input button with a js function to send the form data.
In my case, I did this:
<!-- At the top of my webpage -->
<script language='Javascript'>
function loadingAjax(div_id,user,date1,date2)
{
$("#"+div_id).html('<br><center><img src="images/loading.gif"><br><br><font color="#006699" face="arial" size="4"><b>Loading data<br>VPlease wait ...</b></font></center>');
$.ajax({
type: "POST",
url: "activities.php?USER="+user+"&DATE1="+date1+"&DATE2="+date2,
success: function(msg){
$("#"+div_id).html(msg);
}
});
}
</script>
<!-- And here is my form -->
<form id='date_form'>
<input type='text' id='user'><input type='text' id='date1'><input type='text' id='date2'>
<input type='button' onclick="loadingAjax('myDiv',document.getElementById('user').value,document.getElementById('date1').value,document.getElementById('date2').value);">
</form>
This allow to send your form in a separate DIV without having to show to everyone your URL.
MORE: you can even use this function to manage your left side menu selection so that your URL would stay '/index.php' all the time.
Hope this help
Regards
Nico
How do you want to submit the form, using ajax?
If you want to use ajax, you should cancel the default action like you do with your links using e.preventDefault();. Post the javascript that handles the form submit if you need help with that.
If you want to post to page-one.php without using ajax, you could add a header() redirect after the php code that processes the form to redirect to the page that you would like to show after the form gets submitted.
As you are loading content by ajax,
You can post content to page-one.php and redirect user to it's previous page. But it will be difficult manage and show error, success, notification message like form validation errors etc.
Another and I think best solution is to use ajax form submission
It looks like even the bootstrap demo here doesn't work on iOS. You don't seem to be able to select an item from it on iPhone or iPad.
Is there a fix for this?
There is a quick fix as noted in many of the issue comments on github:
https://github.com/twitter/bootstrap/issues/2975#issuecomment-8670606
add this script just before your close html tag:
$('body').on('touchstart.dropdown', '.dropdown-menu', function (e) {
e.stopPropagation();
});
I have tested the above method on both ios5 and 6. It works like a charm
If you wish to modify the bootstrap javascript you could, instead of the fix above, remove touchstart.dropdown.data-api from the html binding for clearMenus near the bottom of the file.
just change this
$('html')
.on('click.dropdown.data-api touchstart.dropdown.data-api', clearMenus)
to this
$('html')
.on('click.dropdown.data-api', clearMenus)
You need to add a customize jquery in your file.If you want to use that then use:
<div class="container">
<div class="btn-group lt category_bg">
<p>Adults</p>
<button class="btn btn-large" data-toggle="dropdown"><cite>0</cite> <span class="caret"></span></button>
<ul class="dropdown-menu ">
<li id='adult_0' onClick="flight_user(this.id)"><a href="#" >0</a></li>
<li id='adult_1' onClick="flight_user(this.id)"><a href="#" >1</a></li>
<li id='adult_2' onClick="flight_user(this.id)"><a href="#" >2</a> </li>
<li id='adult_3' onClick="flight_user(this.id)">3</li>
<li id='adult_4' onClick="flight_user(this.id)">4</li>
</ul>
</div>
</div>
<script src="js/jquery.js"></script>
<script src="js/bootstrap-dropdown.js"></script>
<script>
function flight_user(selected){
var value = jQuery("#" + selected).find('a').text();
jQuery("#" + selected).parent().parent().find('cite').html(value);
}
</script>
I can give you live demo for this if you want
This script solve this problem. Just add this code
$(document).on('click', 'a.your-drop-down-link', function(event){
event.stopPropagation();
event.preventDefault();
if(event.handled !== true) {
if ( $(this).parent().hasClass('open') ) {
$(this).parent().removeClass('open');
}else{
$(this).parent().addClass('open');
}
event.handled = true;
} else {
return false;
}
});