Javascript and JQuery conflict - javascript

I'm not very expert in using javascript and jquery but I'm working with them for a client.
I have encountered a problem using two script: the first one makes a top panel sliding, the second is in a form. This one is used in order to hide or show a particular field basing on the drop down list choice.
I've found that if I disable the first script (the panel), the second script is working fine and vice versa. I tried usign JQuery noConflict() in the head of the page but nothing happened.
Here the code of the first script (sliding panel):
$(document).ready(function () {
// Lets make the top panel toggle based on the click of the show/hide link
$("#sub-panel").click(function () {
// Toggle the bar up
$("#top-panel").slideToggle();
// Settings
var el = $("#shText");
// Lets us know whats inside the element
var state = $("#shText").html();
// Change the state
state = (state == 'Nascondi' ? '<span id="shText">Entra</span>' : '<span id="shText">Nascondi</span>');
// Finally change whats insdide the element ID
el.replaceWith(state);
}); // end sub panel click function
}); // end on DOM
Here the JS code for the form (hide/show field):
$document.addEvent('domready', function () {
$('motivo_contatto').addEvent('change', function () {
if ($('motivo_contatto').value == 'Invia CV') {
$('upload_file').style.visibility = 'visible';
} else {
$('upload_file').style.visibility = 'hidden';
}
});
$('upload_file').style.visibility = 'hidden';
});
});
Can anyone help me ? Thank you and have a nice day!

you're using 2 different ways to add things to happen to the document ready event:
$(document).ready(function(){ ... });
and
$document.addEvent('domready', function() { ... });
maybe if you just use one it works; maybe the code below will work; I put it all in the first option to run code on document ready:
I edited below code and removed all mootools code; so it might work now.
$(document).ready(function(){
// Lets make the top panel toggle based on the click of the show/hide link
$("#sub-panel").click(function(){
// Toggle the bar up
$("#top-panel").slideToggle();
// Settings
var el = $("#shText");
// Lets us know whats inside the element
var state = $("#shText").html();
// Change the state
state = (state == 'Nascondi' ? '<span id="shText">Entra</span>' : '<span id="shText">Nascondi</span>');
// Finally change whats insdide the element ID
el.replaceWith(state);
}); // end sub panel click function
document.getElementById('motivo_contatto').onchange = function() {
if(document.getElementById('motivo_contatto').value == 'Invia CV') {
document.getElementById('upload_file').style.visibility = 'visible';
} else {
document.getElementById('upload_file').style.visibility = 'hidden';
}
};
document.getElementById('upload_file').style.visibility = 'hidden';
}); // end on DOM

Mixing up two different libraries. Not a good idea.
If you want to keep on following on that pattern, wrap one of the function on a different function and call if from another.
Like:
function moo() {
$('motivo_contatto').addEvent('change', function () {
if ($('motivo_contatto').value == 'Invia CV') {
$('upload_file').style.visibility = 'visible';
} else {
$('upload_file').style.visibility = 'hidden';
}
});
$('upload_file').style.visibility = 'hidden';
});
}
Then call it from another
$(document).ready(function () {
moo(); // Call the moo function
// Lets make the top panel toggle based on the click of the show/hide link
$("#sub-panel").click(function () {
// Toggle the bar up
$("#top-panel").slideToggle();
// Settings
var el = $("#shText");
// Lets us know whats inside the element
var state = $("#shText").html();
// Change the state
state = (state == 'Nascondi' ? '<span id="shText">Entra</span>' : '<span id="shText">Nascondi</span>');
// Finally change whats insdide the element ID
el.replaceWith(state);
}); // end sub panel click function
}); // end on DOM
Check this answer, if you want to use both libraries side by side

Related

HTML Component That Is Fetched With JavaScript Not Responding To Click Event

I have an HTML component that is fetched when user clicks on a button. This component/modal is used to change a user's profile image (this is processed with PHP). The JavaScript fetch() happens with the following code:
var newProfileImageButton = document.getElementById('replace-profile-photo'),
changeProfileImageWrapper = document.getElementById('change-profile-image-wrapper'),
profileImageModalPath = "modals/change-profile-image.php";
newProfileImageButton.addEventListener('click', function(){
fetch(profileImageModalPath)
.then((response) => {
return response.text();
})
.then((component)=>{
changeProfileImageWrapper.innerHTML = component;
})
.catch((error => {console.log(error)}))
})
This fetched component includes a 'close' button should the user wish to close the modal and not update their profile image.
When I click the close button though nothing is happening. I have the script below - is the issue to do with the fact the Javascript has loaded before the component/modal is fetched? And if so how do I fix this? I guess I could just toggle display:none off and on for this component but would prefer to fetch it if possible.
Note: The button is responding to CSS hover events so I'm confident it's not an HTML / CSS markup issue.
// close button is part of the HTML component that is fetched
var closeComponent = document.getElementById('form-close-x')
if (closeComponent) {
closeComponent.addEventListener('click', function(){
// Hide the main component wrapper so component disappears
changeProfileImageWrapper.style.display = 'none';
})
}
I've also tried using the following code, which I found in a similar question, but this doesn't work either (it was suggested this was a duplicate question).
var closeComponent = document.getElementById('form-close-x')
if (closeComponent) {
closeComponent.addEventListener('click', function(e){
if (e.target.id == 'form-close-x') {
changeProfileImageWrapper.style.display = 'none';
}
})
}
Try this:
// var closeComponent = document.getElementById('form-close-x') <-- remove
// if (closeComponent) { <-- remove
document.addEventListener('click', function(e){
if (e.target.id === 'form-close-x') {
changeProfileImageWrapper.style.display = 'none';
}
})
//} <-- remove

JQuery $.post callback firing a function that never finishes

Here's the problem. I'm making a callback to the server that receives an MVC partial page. It's been working great, it calls the success function and all that. However, I'm calling a function after which iterates through specific elements:
$(".tool-fields.in div.collapse, .common-fields div.collapse").each(...)
Inside this, I'm checking for a specific attribute (custom one using data-) which is also working great; however; the iterator never finishes. No error messages are given, the program doesn't hold up. It just quits.
Here's the function with the iterator
function HideShow() {
$(".tool-fields.in div.collapse, .common-fields div.collapse").each(function () {
if (IsDataYesNoHide(this)) {
$(this).collapse("show");
}
else
$(this).collapse("hide");
});
alert("test");
}
Here's the function called in that, "IsDataYesNoHide":
function IsDataYesNoHide(element) {
var $element = $(element);
var datayesnohide = $element.attr("data-yes-no-hide");
if (datayesnohide !== undefined) {
var array = datayesnohide.split(";");
var returnAnswer = true;
for (var i in array) {
var answer = array[i].split("=")[1];
returnAnswer = returnAnswer && (answer.toLowerCase() === "true");
}
return returnAnswer;
}
else {
return false;
}
}
This is the way the attribute appears
data-yes-no-hide="pKanban_Val=true;pTwoBoxSystem_Val=true;"
EDIT: Per request, here is the jquery $.post
$.post(path + conPath + '/GrabDetails', $.param({ data: dataArr }, true), function (data) {
ToggleLoader(false); //Page load finished so the spinner should stop
if (data !== "") { //if we got anything back of if there wasn't a ghost record
$container.find(".container").first().append(data); //add the content
var $changes = $("#Changes"); //grab the changes
var $details = $("#details"); //grab the current
SplitPage($container, $details, $changes); //Just CSS changes
MoveApproveReject($changes); //Moves buttons to the left of the screen
MarkAsDifferent($changes, $details) //Adds the data- attribute and colors differences
}
else {
$(".Details .modal-content").removeClass("extra-wide"); //Normal page
$(".Details input[type=radio]").each(function () {
CheckOptionalFields(this);
});
}
HideShow(); //Hide or show fields by business logic
});
For a while, I thought the jquery collapse was breaking, but putting the simple alert('test') showed me what was happening. It just was never finishing.
Are there specific lengths of time a callback function can be called from a jquery postback? I'm loading everything in modal views which would indicate "oh maybe jquery is included twice", but I've already had that problem for other things and have made sure that it only ever includes once. As in the include is only once in the entire app and the layout is only applied to the main page.
I'm open to any possibilities.
Thanks!
~Brandon
Found the problem. I had a variable that was sometimes being set as undefined cause it to silently crash. I have no idea why there was no error message.

Prevent calling ajax on scroll when already called

I have a plugin that tells me if an element is visible in the viewport with $('#element').visible() (set to true when visible).
Now I want to create a function that I scroll down a page and load new content with ajax. I have this so far:
window.onscroll = function() {
console.log($('#ele').visible());
if ($('#ele').visible()) {
//ajax call comes here
}
};
As soon as I see the element my log shows true:
I don't have problems implementing the ajax-request now, but shouldn't I block this function to occur only once? How could I prevent that a new element that already has been loaded to load again (prevent using ajax again)?
I thought of using a boolean-variable, but my problem is that I don't know how to implement that because if I set a variable, how would the browser know it's value? Because on every move of my mousewheel it cant remember what that variable's value was?
EDIT:
I tried the code of Ismail and it never reaches the ajax call (alert won't show).
window.onscroll = function() {
var ajaxExecuted = false;
var ele = $('#load_more').visible();
console.log(ele);
return function() {
if (ajaxExecuted) return;
if (ele) {
alert("OK");
var ajaxArray;
ajaxArray = { page: 2 }
ajaxLoadContent(ajaxArray, "load_more", "ajax_load");
ajaxExecuted = true;
}
}
};
You can use this:
window.onscroll = (function() {
var ajaxExecuted = false;
return function() {
if(ajaxExecuted) return;
if ($('#ele').visible()) {
$.ajax({...}).success(function() {
//Your code here;
ajaxExecuted = true;
});
}
}
})();
One easy solution: set a boolean to true when the element first becomes visible and set it to false when it stops being visible. Only fire the request if those states mismatch (i.e. if it's visible but the boolean is false - that means it's the first time you've seen the window. You'd then set the bool afterwards so it won't fire off anymore until it disappears and reappears again).

Ubuntu HTML5 App: Change Tab on JS command

First Question here, too! Yay! Just moved this from AskUbuntu.
I am just about to finish a little private project for gaining some experience where i try to change the app layout so it works as a normal website (on Jimdo, so it was quite of a challenge first) without much JavaScript required but is fully functional on mobile view.
Since Jimdo serves naturally only the actual site, I had to implement an
if (activeTab.getAttribute('jimdo-target') != null)
location.href = activeTab.getAttribute('jimdo-target');
redirect into the __doSelectTab() function in tabs.js . (In js I took the values from the jimdo menu string to build the TABS menu with this link attribute)
Now everything works fine exept at page load the first tab is selected. I got it to set the .active and .inactive classes right easily, but it is not shifted to the left.
So my next idea is to let it initialize as always and then send a command to change to the current tab.
Do you have any idea how to manage this? I couldn't because of the this.thisandthat element I apparently don't really understand...
Most of you answering have the toolkit and the whole code, but I am listing the select function part of the tabs.js:
__doSelectTab: function(tabElement, forcedSelection) {
if ( ! tabElement)
return;
if (tabElement.getAttribute("data-role") !== 'tabitem')
return;
if (forcedSelection ||
(Array.prototype.slice.call(tabElement.classList)).indexOf('inactive') > -1) {
window.clearTimeout(t2);
activeTab = this._tabs.querySelector('[data-role="tabitem"].active');
offsetX = this.offsetLeft;
this._tabs.style['-webkit-transition-duration'] = '.3s';
this._tabs.style.webkitTransform = 'translate3d(-' + offsetX + 'px,0,0)';
this.__updateActiveTab(tabElement, activeTab);
if (activeTab.getAttribute('jimdo-target') != null)
location.href = activeTab.getAttribute('jimdo-target');
[].forEach.call(this._tabs.querySelectorAll('[data-role="tabitem"]:not(.active)'), function (e) {
e.classList.remove('inactive');
});
var targetPageId = tabElement.getAttribute('data-page');
this.activate(targetPageId);
this.__dispatchTabChangedEvent(targetPageId);
} else {
[].forEach.call(this._tabs.querySelectorAll('[data-role="tabitem"]:not(.active)'), function (el) {
el.classList.toggle('inactive');
});
var self = this;
t2 = window.setTimeout(function () {
var nonActiveTabs = self._tabs.querySelectorAll('[data-role="tabitem"]:not(.active)');
[].forEach.call(nonActiveTabs, function (el) {
el.classList.toggle('inactive');
});
}, 3000);
}
},
...and my app.js hasn't anything special:
var UI = new UbuntuUI();
document.addEventListener('deviceready', function() { console.log('device ready') }, true);
$(document).ready(function () {
recreate_jimdo_nav();
UI.init();
});
So meanwhile found a simple workaround, however I'd still like to know if there is another way. Eventually I noticed the __doSelectTab() function is the one that executes the click, so it does nothing but to show the other tab names when they are hidden first. so I added the global value
var jnavinitialized = false;
at the beginning of the tabs.js and run
var t = this;
setTimeout(function(){t.__doSelectTab(t._tabs.querySelector('[data-role="tabitem"].jnav-current'))}, 0);
setTimeout(function(){t.__doSelectTab(t._tabs.querySelector('[data-role="tabitem"].jnav-current'))}, 1);
setTimeout(function(){jnavinitialized = true;}, 10);
at the top of the __setupInitialTabVisibility() function. Then I changed the location.href command to
if (activeTab.getAttribute('jimdo-target') != null && jnavinitialized)
location.href = activeTab.getAttribute('jimdo-target');
And it works. But originally I searched for a way to change the tab on command, not to run the command for selecting twice. So if you know a better or cleaner way, you are welcome!

Off click of focused div not activating on jQuery function

Here is my HTML
$html .= " <td><div class='edit_course' data-id='{$id}' data-type='_title' contenteditable='true'>{$obj->title}</div></td>";
Here is my jQuery:
var selector = 'div[contenteditable="true"]';
// initialize the "save" function
$(selector).focus(function(e) {
content_holder = $(this);
content = content_holder.html();
var id = $(this).data('id');
var type = $(this).data('type');
alert( id + type)
// one click outside the editable area saves the content
$('body').one('click', function(e) {
// but not if the content didn't change
if ($(e.target).is(selector) || content == content_holder.html()) {
return;
}
// Edited out AJAX call
});
});
The problem is, when I click on the div, the alert below triggers. When I click outside of the div (after the edit has been made), nothing happens. Can anyone see what is happening?
First click let's user edit content in div. The first click outside, should make ajax call to save.
EDIT: From recommendation below.
Here is new code this works perfectly except it calls the DB every time, all I need is a check to do that only if data is different and I think I got it from there.
Edit2: Final Code
var original_value = '';
$(".edit_course").focus(function(e) {
original_value = $(this).html();
});
// initialize the "save" function
$(".edit_course").blur(function(e) {
var content = $(this).html();
var id = $(this).data('id');
var type = $(this).data('type');
if (content !== original_value) {
// Ajax edited out
}
});
You're not using one() correctly. What you should do is run the AJAX when focus is taken away from the div. Using blur() would probably be your best bet here.
$('body').blur(function(e) {
// your code here...
});

Categories