How can I make my multiple buttons and functions expandable - javascript

I created a function to add different specific words to a Sharepoint when a button is selected/clicked, but the script is not expandable. How can I make multiple buttons function and function more expandable and grow when another set of words are needed to add to the SharePoint list. It would be nice to not have a growing list of buttons and functions. My working but not to efficient/expandable code is below. I appreciate the help I can get with this issue.
$(document).ready(function(){
jQuery(document).on("click", '.picture1', function(){
InsertItem1();
});
jQuery(document).on("click", '.picture2', function(){
InsertItem2();
});
jQuery(document).on("click", '.picture3', function(){
InsertItem3();
});
jQuery(document).on("click", '.picture4', function(){
InsertItem4();
});
});
function InsertItem1() { updateData("Selected"); }
function InsertItem2() { updateData("Field-3"); }
function InsertItem3() { updateData("Field-2"); }
function InsertItem4() { updateData("Field-1"); }
function updateData(viewhit) {
var restendpoint = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getByTitle('Views')/items";
$.ajax({
url: restendpoint,
type: "POST",
data: JSON.stringify({
__metadata: {
type: "SP.Data.ViewsListItem"
},
Title: "Podcast",
Views: viewhit
}),
headers: {
"Accept": "application/json;odata=verbose",
"Content-Type": "application/json;odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val(),
"X-HTTP-Method": "POST"
},
success: function() {
console.log("Item added to the SharePoint list");
},
error: function() {
console.log("Error Occurred!");
}
});
}

Try my best to restructure your code into a more expandable/resuable way.
My approach is to select all element which having class name begin with naming picture at first,
$('[class^=picture]')
then registet event listener to all at once and twitching the arguments using switch condition based on element's class name as shown below, not sure if it fits your condition or not.
Edited:
Suddenly think of another shorter attempt which using an object so I include it in the snippet for your reference.
const controller_object = {
'picture1': 'Selected',
'picture2': 'Field-3',
'picture3': 'Field-2',
'picture4': 'Field-1'
};
$('[class^=picture]').on('click', function(e) {
const elementClass = $(this).attr('class');
/*/ // add a slash (/) at the beginning of this line to activate 1st attempt
// 1st attempt with switch
let viewHit;
switch(elementClass)
{
case 'picture1':
viewHit = 'Selected';
break;
case 'picture2':
viewHit = 'Field-3';
break;
case 'picture3':
viewHit = 'Field-2';
break;
case 'picture4':
viewHit = 'Field-1';
break;
case 'default':
break;
}
updateData(viewHit);
/*/
// 2nd attempt with object controller
updateData(controller_object[elementClass]);
//*/
});
function updateData(viewhit) {
// simple writing to mimic your function calls
alert(viewhit);
}
[class^=picture] {
border: 1px dashed black;
padding: 3px 6px;
margin: 5px;
cursor: pointer;
}
[class^=picture]:hover {
background-color: lightgray;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="picture1">Picture 1</div>
<div class="picture2">Picture 2</div>
<div class="picture3">Picture 3</div>
<div class="picture4">Picture 4</div>
Hope it helps and Happy coding !

Related

Set an "unattainable" drop down list background to be over other elements

I have an autocomplete function which works fine, but when the drop down list appears, it is almost unreadable because it is over other elements.
The problem is that i don't create the drop down list myself, it is created from a request sent to a database and i can't manage to identify exactly which element's property i have to modify in order to have a dropdown box that would be like a block displayed over the other elements.
I tried to identify which elements were created when the dropdown list appears but it doesn't seem to do anything. Here's my result :
and the css part i coded :
.ui-helper-hidden-accessible {
z-index: 1000;
display: block;
background: #f9f9f9;
border-top: 1px solid blue;
}
The Autocomplete function ( not sure if it helps but doesn't cost anything to put it here )
// Auto-Complete sur liste publicitaire
$("#ag_pub_publicitaire_nompublicitaire").autocomplete
({
source: function (request, response) {
$.ajax
({
url: "https://cms.ag-carto.com/CMS_service/ws_ag_sgbdr_json/ag_sgbdr.asmx/ag_pub_publicitaire_get_list",
data: "{'ag_sql_query_text':'" + request.term + "','count':'0'}",
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
dataFilter: function (data) { return data; },
success: function (data) {
var found = $.map(data.d, function (item) {
return {
value: item.ag_pub_publicitaire_nompublicitaire,
ag_pub_publicitaire_entityid: item.ag_pub_publicitaire_entityid,
};
});
if (found.length == 0) {
$('#ag_pub_publicitaire_nompublicitaire').val("Pas de publicitaire Trouvé ! Ressaisissez...");
$('#ag_pub_publicitaire_entityd').val("");
//alert("Pas de publicitaire Trouvé ! Ressaisissez...");
}
else {
//$('#infopconso').val(found.length + " Compteurs Trouvés ! Choisissez dans la liste...");
//$('#infopconso').val(found.length + " Compteurs Trouvés ! Choisissez dans la liste...");
}
response(found);
},
error: function (XMLHttpRequest, textStatus, errorThrown)
{
alert(textStatus);
}
});
},
minLength: 3,
select: function (event, ui)
{
if (ui.item.ag_pub_publicitaire_nompublicitaire == "-1") {
$('#ag_pub_publicitaire_nompublicitaire').val("");
$('#ag_pub_publicitaire_entityd').val("");
$('#ag_pub_publicitaire_nompublicitaire').focus();
}
else {
$("#ag_pub_publicitaire_entityid").val(ui.item.ag_pub_publicitaire_entityid);
}
}
});
Right now i think that i'm not aiming at the right class, but i don't really know what to try next. Any help would be greatly appreciated :)
Thanks in advance and have a great day :)
You are targeting wrong div css..
Here is the fix .Its targeting the ul with id #ui-id-1 which is showing the autocomplete fucntionallity..
.ui-widget.ui-widget-content {
z-index: 1000;
display: block;
background: #f9f9f9;
border-top: 1px solid blue;
}
Not really proud of this one but I didn't included the jquery-ui.css file in my html, that's why it it didn't work the way I wanted

AJAX Complete Handler not beeing fired

After some hard work on the backend of my Web Application I noticed that the GetMeasure Request takes up to 10 seconds to finish. I decided to apply an overlay so a potential user won't get confused because nothing happens on the screen. No matter if the request is successfull or not the overlay should get removed after the call - so using the complete handler should be the best choice - at least I thought. I really don't get why but in opposite to the success handler the complete handler won't get called.
AJAX Request:
$_loadingCircle = $('<img id="loading" src="http://www.obergurgl.com/_images/layout/loading.gif"/>');
PopulateOverlay($_loadingCircle);
$.ajax({
url: 'CoDTracker/Home/GetMeasures',
type: 'POST',
dataType: "html",
data: {
buID: buid,
aID: aid,
lID: lid
},
success: function (data) {
$('#measures').html(data);
},
complete: function () {
$_overlay.remove();
}
});
The request ends with status 200 (successfull) but the overlay won't get removed. I'm sure that the request completed because my measures got filled into the page while the circle spins as crazy instead of disappearing.
Am I doing something wrong?
Edit:
Overlay-definition
function PopulateOverlay($content) {
$_overlay = $('<div class="overlay">');
$content.appendTo($_overlay);
$_overlay.appendTo('body');
}
Your $_overlay is defined incorrectly.
Please use:
$_overlay = $('div.overlay');
And please refer to jQuery Selectors for more information:
https://api.jquery.com/category/selectors/
The way to select a div with a particular class, is not to copy the entire <div class="">, but rather as I did in the example above.
EDIT: in fact, if you make this change, your PopulateOverlay will no longer work, so you should rather just select it without assigning it to a variable:
complete: function () {
$('div.overlay').remove();
}
Because overlay is appended in the DOM, you should remove it with .class:
complete: function () {
$('.overlay').remove();
}
First, if there's no error, and that's all your code, it should work fine.
Let's try to make an example, with a mimic function to mimic the behavior of ajax complete, we can write it like:
var $_overlay = null; // We assume you define it somewhere, and it's visible to all your functions.
function PopulateOverlay($content) {
$_overlay = $('<div class="overlay">');
$content.appendTo($_overlay);
$_overlay.appendTo('body');
}
// See this as an ajax call with 2 sec delay.
function mimic(cb) {
setTimeout(cb, 2000);
}
function theWorks() {
$someEle = $('<div class="example">example</div>');
PopulateOverlay($someEle);
mimic(function() {
$_overlay.remove();
});
}
$(function() {
theWorks();
});
.overlay {
display: block;
width: 100px;
height: 100px;
background-color: black;
}
.example {
color: cyan;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
So I guess, that your codes, is inside another function, and you may call it many times, let's make a button, and click to trigger it:
var $_overlay = null; // We assume you define it somewhere, and it's visible to all your functions.
function PopulateOverlay($content) {
$_overlay = $('<div class="overlay">');
$content.appendTo($_overlay);
$_overlay.appendTo('body');
}
// See this as an ajax call with 2 sec delay.
function mimic(cb) {
setTimeout(cb, 2000);
}
function theWorks() {
$someEle = $('<div class="example">example</div>');
PopulateOverlay($someEle);
mimic(function() {
debugger;
$_overlay.remove();
});
}
$(function() {
$('#click').on('click', theWorks);
});
.overlay {
display: block;
width: 100px;
height: 100px;
background-color: black;
}
.example {
color: cyan;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="click">Click</button>
Now, if click the button before the previous pop out disappear, some popouts last forever.
Why? Because when you click again, your $_overlay will be assign to a newly created element, which means you lost the reference to the previous pop out, and when later the remove works takes action, it only remove the newest one, and all the following removes, are about to remove something that is not on the page, so you won't see effects, and older popouts remains.
We could fix it, by catch the current element in another variable when you're executing your codes. This would work if you expect many pop outs.
var $_overlay = null; // We assume you define it somewhere, and it's visible to all your functions.
function PopulateOverlay($content) {
$_overlay = $('<div class="overlay">');
$content.appendTo($_overlay);
$_overlay.appendTo('body');
}
// See this as an ajax call with 2 sec delay.
function mimic(cb) {
setTimeout(cb, 2000);
}
function theWorks() {
$someEle = $('<div class="example">example</div>');
PopulateOverlay($someEle);
// Cache the current overlay, or simply move $_overlay here, if no other using it.
var $_curOverlay = $_overlay;
mimic(function() {
$_curOverlay.remove();
});
}
$(function() {
$('#click').on('click', theWorks);
});
.overlay {
display: block;
width: 100px;
height: 100px;
background-color: black;
}
.example {
color: cyan;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="click">Click</button>
Or as what Laurens Swart suggest, simply toggle the state if you only need one pop out at a time.
var $_overlay = $('.overlay');
function PopulateOverlay($content) {
$_overlay
.empty() // Clear previous
.append($content) // Append the content
.show(); // Make it visible.
}
// See this as an ajax call with 2 sec delay.
function mimic(cb) {
setTimeout(cb, 2000);
}
function theWorks() {
$someEle = $('<div class="example">example</div>');
PopulateOverlay($someEle);
mimic(function() {
$_overlay.hide(); // Instead of remove, we make it hide, so we can reuse it later.
});
}
$(function() {
$('#click').on('click', theWorks);
});
.overlay {
display: none;
width: 100px;
height: 100px;
background-color: black;
}
.example {
color: cyan;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="click">Click</button>
<div class="overlay"></div>

Simplifying onclick jquery/JavaScript functions

I am trying to simplify all .js functions on the site to improve page load speed and overall performance of my site. Managed to do most of it on my own, but got stack when started to minimize couple of functions that are mostly call backs and onclick functions called from the functions.js in the page head.
SO here is my question, how can I make one function out of the following 2 to make script shorter and without loosing any functionality, or if there any alternative way to make it all simpler than it currently is?
function user_dialog(dialog_content, download_button) {
if (typeof jQuery.ui != 'undefined') {
$("#dialog").attr("title", "Lets share it").html(dialog_content);
$("#dialog").dialog({
modal: false,
width: 400,
buttons: {
Cancel: function() {
$(this).dialog("close");
},
"Download": function () {
$(this).dialog("close");
window.location = download_button;
}
}
});
} else {
window.location = download_button;
}
}
function user_notice(link_source) {
download_link = $(link_source).attr("href");
$.ajax({
type: "POST",
url: "/includes/json.php",
data: "action=reminder&thepath=" + download_link,
dataType: "json",
error: function() {
window.location = download_link;
},
success: function(resp_dialog) {
if (resp_dialog.status == 1) {
user_dialog(resp_dialog.html, download_link);
}
}
});
}
Thanks for your help in advance!!!
add an action variable in your function vars, like us_action and un_action then use an if statement to say if is us_acion, perform this else if un_action do this

optimizing colorbox and adding extra jquery

I have two problems
I am trying to open a jQuery colorbox and it is very slow. The reason is I am trying to get html content from a different page (I cannot use iframe because I just need a part of this page). The following code works but it takes time after the button is clicked:
$(document).ready(function() {
$(".cart-link a").click(function(event) {
$(this).colorbox.close();
});
$(".rest-menuitem a").click(function(event) {
event.preventDefault();
var result = null;
var sURL = $(this).attr("href");
$.colorbox({
html: function() {
$.ajax({
url: sURL,
type: 'get',
dataType: 'html',
async: false,
success: function(data) {
result = data;
}
});
return $(result).find('.product');
},
width: '650px',
height: '10px',
onComplete: function() {
$(this).colorbox.resize();
}
});
});
});
I want to know if there is a alternative way to do it. I dont mind if the colorbox popup and then takes time to load the content. The above version can be fount at this url (http://delivery3.water-7.com/index.php/restaurants/manufacturers/3/Barcelona-Restaurant-&-Winebar/products).
I am also trying to close the colorbox when a user clicks on add to cart. But some reason it is not triggered. $(".cart-link a").click is not triggered when I click on add to cart. Is there a special way to add jquery to colorbox content?
Try this instead:
$(".rest-menuitem a").colorbox({
href: function(){
return $(this).attr('href') + ' .products';
},
width: '650px',
height: '10px',
onComplete: function() {
$(this).colorbox.resize();
}
});
ColorBox uses jQuery's load() method for it's ajax handling, so you just need to add the desired selector to the link's href.
For your question 2 can you try this ?
$(document).ready(function() {
$(".cart-link a").live('click',function(event) {
$(this).colorbox.close();
});
});
For your question 1..it will be slow since you are fetching it from different page.Use a different logic for that
For your question no 1
$('selector').colorbox({onLoad: function() { /*Intially load a empty color box with only <div id="contenttoload"></div> (No other html content */
$.ajax({
url :'Your url',
data : {}, //data to send if any
type : "POST" //or get
success:function(data){ /*data means the stuff you want to show in color box which you must return from the other page*/
$('#contenttoload').html(data); //data should be well formatted i mean add your css,classes etc from the server itself */
}
});
}});

Can't get toggling between two colors for div when clicking a link to work

I have this link:
<div id='up_arrow_div'>
<%= link_to "⇑".html_safe, video_votes_path( :video_id => video.id, :type => "up" ), :method => :post, :remote => true, :class => 'up_arrow' %>
</div>
as well as a down vote one that sends a POST request and inserts a vote into the database. I'm trying to set up styling so that it changes colors when you click it. Here's the initial CSS:
a.up_arrow:link, a.down_arrow:link {
color: black;
text-decoration: none;
font-size: 25px;
margin-left: 7px;
}
#up_arrow_div, #down_arrow_div {
display:block;
background-color:#DFEAF4;
width:30px;
}
The CSS creates a colored square div around the arrow-shaped link. Then I have this jQuery:
$('a.up_arrow').toggle(function () {
$('#up_arrow_div').css("background-color", "#19558D");
}, function () {
$('#up_arrow_div').css("background-color", "#E9DEDE;");
});
$('a.down_arrow').toggle(function() {
$('#down_arrow_div').css("background-color", "#19558D");
}, function () {
$('#down_arrow_div').css("background-color", "#E9DEDE;");
});
This doesn't seem to work though. What happens is that first of all, the voting becomes disabled. Also, the color of the div changes once, but it doesn't change back when you click it again. What am I doing wrong and how can I fix it?
UPDATE:
As requested, here is the generated HTML markup:
<div id="voting_div">
<div id="up_arrow_div">
⇑
</div>
<div id="vote_display">
<p id="votes">0 Votes</p>
</div>
<div id="down_arrow_div">
⇓
</div>
</div>
UPDATE 2:
Here's the JS code I'm using now, as explained by the answer below:
var toggleVoting = function() {
if ($(this).parent().hasClass("voted")) {
return "unvoted";
}
else {
return "voted";
}
};
$('a.up_arrow').click(function() {
$(this).parent().toggleClass(toggleVoting);
});
$('a.down_arrow').click(function() {
$(this).parent().toggleClass(toggleVoting);
});
The behavior of this code is that when I vote, the div has the class voted added to it, and when I vote again, the voted class is removed, but the unvoted class is not added. I need to add the unvoted class when the voted class is removed.
Remove the semicolons (;) from the color you're passing to .css() in your second toggle function for each selector (#E9DEDE instead of #E9DEDE;):
$('a.up_arrow').toggle(function () {
$('#up_arrow_div').css("background-color", "#19558D");
}, function () {
$('#up_arrow_div').css("background-color", "#E9DEDE");
});
$('a.down_arrow').toggle(function() {
$('#down_arrow_div').css("background-color", "#19558D");
}, function () {
$('#down_arrow_div').css("background-color", "#E9DEDE");
});
Update: As you pointed out, the link won't be followed when the toggle() code is applied. This is because jQuery cancels the default action of the link when that function is executed. To get around that, you could write your own code that uses toggleClass() instead:
JavaScript:
var toggleVoting = function() {
if ($(this).hasClass("voted")) {
return "unvoted";
}
else {
return "voted";
}
};
$('a.up_arrow').click(function() {
$("#up_arrow_div").toggleClass(toggleVoting);
});
$('a.down_arrow').click(function() {
$("#down_arrow_div").toggleClass(toggleVoting);
});
CSS:
.voted { background-color: #19558D; }
.unvoted { background-color: #E9DEDE; }
Update 2: To remove voted/unvoted:
var toggleVoting = function() {
var $this = $(this);
if ($this.hasClass("voted")) {
$this.removeClass("voted");
return "unvoted";
}
else {
$this.removeClass("unvoted");
return "voted";
}
};
Update 3, based on comments below:
var toggleVoting = function() {
var $this = $(this);
if ($this.hasClass("voted")) {
$this.removeClass("voted");
return "unvoted";
}
else {
$this.removeClass("unvoted");
return "voted";
}
};
$('a.up_arrow').click(function(e) {
e.preventDefault();
var $downArrow = $("#down_arrow_div");
if ($downArrow.hasClass("voted")) {
$downArrow.addClass("unvoted").removeClass("voted");
}
$("#up_arrow_div").toggleClass(toggleVoting);
});
$('a.down_arrow').click(function(e) {
e.preventDefault();
var $upArrow = $("#up_arrow_div");
if ($upArrow.hasClass("voted")) {
$upArrow.addClass("unvoted").removeClass("voted");
}
$("#down_arrow_div").toggleClass(toggleVoting);
});
Here's a working example: http://jsfiddle.net/andrewwhitaker/QuA2K/2/

Categories

Resources