Jquery is resetting after dynamic changes - javascript

I have a chartist.js bar graph. I want to customize x-axis labels. I wrote some following jquery for flipping first and last name and then add '...' at the end if the length of the text is more than 11 characters.
$(function () {
$('#AssignedLineChart .ct-labels, #ResolvedBarChart .ct-labels').find('.ct-label.ct-horizontal').each(function () {
var label = $(this).text();
var splitLabel = label.split(",");
var newLabel = splitLabel[1] + ", "+splitLabel[0];
if (newLabel.length > 13) {
newLabel = newLabel.substring(0, 10) + "...";
}
$(this).text(newLabel);
});
});
It applied fine when I load the page first time. There are some select options on bar charts for displaying individual ranges. When I select them the labels go back to their previous state. Selecting options are changing DOM. This also happens when I open inspect element tab.
Is there a way to use find or each method on dynamically changed elements?

$(function () {
This is only applied when the page finishes loading and get fired 1 time only.
Selecting options are changing DOM.
So the current process is like:
Page finishes loading.
The label got changed by document ready event. (*)
The label got changed by other events, this case, the select options. (**)
So, it changed the DOM dynamically and nothing like above (*) changes the label again.
So, to change the label after select options, you need to change it in the callback function of what is done after select options in the above mentioned (**).

Related

Select options disappearing when appending new option

I'm currently creating a interface to select an option from one select element on double click, and append it to another select element.
The issue I am coming across is when doing so, it is added and visible, however all other options disappear in the destination select, until I click on the option and then click off.
You can see this in action here: https://i.imgur.com/jSXoIAi.gifv
My current implementation is as follows:
$('body').on('dblclick', '#availableColumnsSelect > option', function (e) {
var option = $(this);
//Add option to destination
displayColumnsSelect.append($('<option>', { value: option.val(), text: option.val() }));
//Remove option from source
option.remove();
//Sort the select options
sortSelect("#displayColumnsSelect");
var optionsAvailable = $("#availableColumnsSelect > option:not([disabled])").length;
if (optionsAvailable == 0) {
$("#noSelectedText").removeClass('hidden');
}
$("#noSelectedText").addClass('hidden');
});
The underlying HTML is being constructed exactly how it should.
Any ideas?
As pointed out the issue was with the sortSelection function. I'm not quite sure why, but regardless I don't actually require this function anymore.
Removing said function has resolved the issue :)

Create a function to hide divs

I want to display tables when a selection is made in a form and a 'Generate Factsheet' button is clicked. I've got a working code where I individually hide other divs when displaying the one I am interested in. Since I have several options in the form (and hence several corresponding divs in which the respective tables are enclosed), the final code appears bulky. I want to write a function to hide other divs whiles displaying the one I am interested in. This is the code I currently have:
var tableDivs = ['tableOPVDiv','tablePneumoDiv','tableRotaDiv'];
var selectedVaccine;
var selectedTableDiv;
function generateFactsheetFunction(){
// Selecting the vaccine chosen from the dropdown
var e = document.getElementById("selectVaccine");
selectedVaccine = e.options[e.selectedIndex].text;
console.log("selectedVaccine: ", selectedVaccine);
if (selectedVaccine=="Rotavirus Vaccine"){
selectedTableDiv='tableRotaDiv';
console.log("rotavirus selected");
hideOtherTables();
} else if (selectedVaccine=="Polio Vaccine"){
console.log("polio selected");
selectedTableDiv='tableOPVDiv';
hideOtherTables();
} else if (selectedVaccine=="Pneumococcal Vaccine"){
console.log("pneumo selected");
selectedTableDiv='tablePneumoDiv';
hideOtherTables();
}
}
function hideOtherTables(){
var testa = tableDivs.indexOf(selectedTableDiv);
console.log("tableDivs[testa]: ", tableDivs[testa]);
console.log("testa: ", testa);
testb = tableDivs[testa];
console.log("testb: ", testb);
document.getElementById(tableDivs[testa]).style.display="block";
/*var newTableDivs=tableDivs.splice(testa);*/
/*for (y=0;y<newTableDivs.length;y++){
document.getElementById(newTableDivs[y]).style.display="none";
}*/
}
The uncommented part works fine. In the commented part, I want to say that for all array elements other than selectedVaccine, I want the display to be:
document.getElementById(tableDivs[testa]).style.display="none";
I cannot splice the data because the selections are repititive (the selections are from a form). What is the way to set the visibility of tableDivs associated with other selections to be none.
Why should you change the display property of each and every division seperately? give a common class name to all the divisions and hide them all at once and then display only the required table.
$(".yourClass").hide();
document.getElementById(tableDivs[testa]).style.display="block";
You will have to use the jQuery Library too.
If you are not familiar with jQuery then use the for loop to hide all the tables first and then display only the required table.
for (y=0;y<TableDivs.length;y++){//you need not create newTableDivs
document.getElementById(TableDivs[y]).style.display="none";
}
document.getElementById(tableDivs[testa]).style.display="block";
i.e you just have to interchange the order of execution. ;)
Cannot read property 'style' of null this means that document.getElementById(tableDivs[y]) return null and can not find this element
try to write
document.getElementById("ElementId")

How to refresh DataTables after call to page event?

Here is my scenario ...
I am using pagination with DataTables. My first column is css styled based upon data that is passed in. So, I display the correct colored icon for the property of the item in the table. Everything on page 1 displays correctly. Just doing the basics, everything on further pages does not get displayed because it is removed from the DOM at that time.
So, I did $('#my_id').on('page.dt', function() {perPageFunctionCall();}).dataTable(so on an so forth)}; to call a function which selects the correct colored flag.
When I click on page 2, nothing gets updated. I click on page 1 again and it redisplays the 1st page correctly. I click on page 2 a second time now and it displays everything correctly this time.
So what is causing the display not to update with my new css the 1st trip but to display properly on subsequent trips? Is there someway to refresh the element or the data table after I am done with my css manipulation?
Well it is one of two things:
Either it is
1: I added
.on( 'order.dt', function () { perPageFunctionCall(); } )
.on( 'search.dt', function () { perPageFunctionCall(); } )
in addition to my page function call.
But more likely everyone's favorite reason:
2: Caching
In either case, it does work flawlessly now as expected.
for refresh resp. table :
var path = "/server_processing.php";
var dt = $('#tableid').DataTable();
dt.clear();
dt.draw();
dt.ajax.url(path).load()

Fundamentally doing something wrong with function calls. Functions do work in the console

This is a solid, proper syntax set of functions, and for the life of me I can't figure out why, but the function ServiceHover() will not run unless I trigger it manually in the console, while it's almost exact equal CategoryHover() runs perfectly each time. It has to be something about the way that I'm calling the functions, and clearly there's something about functions that I fundamentally missed in javascript, because this happens to me often, where I'm unsure why my functions are not executing.
I keep my code all very well commented, so I shouldn't have to explain the functions's purposes, and furthermore, this is more a question of the fundamental execution of the functions rather than their inner functionality. Each function does work if called manually in the console.
//this function generates the content of the page based on which category the user selects,
//which services the user selects, and help maneuver through each stage of the feature selection
//so that the QuoteEngine function can display the user's selected hour count, price per hour
// and total cost of the needed service so that the user can see very clearly what services
//he is getting and where every dollar of his total cost is coming from so that the user can
//make a well informed purchase decision, and be able to clearly understand the services offered
//and related pricing.
$(document).ready(function () {
function BasicDropdown() {
//hide the drop-downs to begin with
//hide element with class dropdown-category
$(".dropdown-category").hide();
//hide element with class dropdown-service
$(".dropdown-service").hide();
//when the category list title is hovered over, show the category drop-down list
//when element with class category is hovered, do this:
$(".category").hover(function () {
//show the list
$(".dropdown-category").show();
//when element with class category is no longer hovered, do this:
}, function () {
//hide the list
$(".dropdown-category").hide();
});
//when the service list title is hovered over, show the service drop-down list
//when element with class service is hovered, do this:
$(".service").hover(function () {
//show the list
$(".dropdown-service").show();
//when element with class service is no longer hovered, do this:
}, function () {
//hide the list
$(".dropdown-service").hide();
});
}
//change the selected service based on an id input
//create a function to change the selected service
function ChangeService(id) {
//clear the service list element
$(".dropdown-service").empty();
//make the name inside the service drop-down title show the new title
$("#ServiceOutput").text(ServiceArray[id][0][1]);
//loop through the chosen section of the service array for as many times as the
//section is in length
for (var i = 0; i < ServiceArray[id].length; i++) {
//each loop, append a paragraph element with a data key equal to the current
//loop count, an id equal to the id of the array area based on the loop count,
//and also insert the element's text according to that loop count also.
$(".dropdown-service").append('<p data-key="' + i + '" id="' + ServiceArray[id][i][0] + '">' + ServiceArray[id][i][1] + "</p>");
}
//set the variable "Category" to be equal to the chosen id.
Category = id;
}
function CategoryHover() {
//make the category drop-down list open and show its list of services
//when the user hovers over an element in the category drop-down, do this:
$(".dropdown-category > p").hover(function () {
//hide the welcome wrapper
$(".welcomeWrapper").hide();
//set the variable "thisKey" based on the value of the data "key" attached
thisKey = $(this).data("key");
//create a variable "outputList" and assign a value to it from "CategoryArray"
outputList = CategoryArray[thisKey];
//set the title of the category drop-down lists title to the currently hovered text
$("#CategoryOutput").text($(this).text());
//call the ChangeService function and pass the variable "thisKey" into it
ChangeService(thisKey);
//show the service drop-down list
$(".dropdown-service").show();
//show the ListOutput element (this shows a short description of the hovered element)
$(".ListOutput").show();
//append the variable "outputList" as the value of a paragraph element
$(".ListOutput").append('<p>' + outputList + '</p>');
}, function () {
//hide the service drop-down list
$(".dropdown-service").hide();
//empty the ListOutput element
$(".ListOutput").empty();
//hide the ListOutput element
$(".ListOutput").hide();
//show the welcome wrapper again
$(".welcomeWrapper").show();
});
}
function ServiceHover() {
//make the service drop-down list open and show the list of services for the category
//when the user hovers over an element in the service drop-down, do this:
$(".dropdown-service > p").hover(function () {
//hide the welcome wrapper
$(".welcomeWrapper").hide();
//set the variable "thisKey" based on the value of the data "key" attached
thisKey = $(this).data("key");
//create a variable "outputList" and assign a value to it from "CategoryArray"
outputList = ServiceArray[Category][thisKey][2][0];
//show the ListOutput element (this shows a short description of the hovered element)
$(".ListOutput").show();
//append the variable "outputList" as the value of a paragraph element
$(".ListOutput").append('<p class="blue">' + outputList + '</p>');
}, function () {
//empty the ListOutput element
$(".ListOutput").empty();
//hide the ListOutput element
$(".ListOutput").hide();
//show the welcome wrapper again
$(".welcomeWrapper").show();
});
}
BasicDropdown();
CategoryHover();
ServiceHover();
//initiate
ChangeService(0);
});
What am I doing wrong with these calls?
JS Fiddle: http://jsfiddle.net/gbJcg/4/
Note: I mentioned in my question but for some reason the update didn't show up, that all of the arrays should be assumed defined. I'll now include them to remove confusion, but it will make the scripts extensively long
Added detail: ChangeCategory works. ChangeService doesn't appear to. If I copy and paste ChangeService, however, in the console, and call it, in the console, the functionality works perfectly. Does that help? I have no idea what I'm doing wrong here...
Well what I know is, since your dropdown-service is added dynamically, you need to delegated it to closest static parent present in the document which is dropdown-service in your case.
$(".dropdown-service").on("mouseenter" ,"p",function () {
..
});
$(".dropdown-service").on("mouseleave" ,"p",function () {
...
});
Since live is deprecated in latest version of jQuery you need to use on delegated event and break the hover into mouseenter and mouseleave function.
fiddle here
Check your console, you have Uncaught ReferenceError: ServiceArray is not defined
This Exception is thrown and the rest of the program is not ran
EDIT: after fiddle changed with the missing Arrays initialization is seems like the code works. I added alerts in the begining of 2 functions to make sure they are called (see http://jsfiddle.net/gbJcg/3/)
EDIT #2:
The call to $(".dropdown-service > p").hover(...) is done when you do not have any elements that respond to ".dropdown-service > p" selector, They are probably added later via ajax or some other html manipulation that is done by js
You should use the equivalent for jquery live instead:
$(document).on("mouseenter",".dropdown-service > p",function() {
....
});
$(document).on("mouseleave",".dropdown-service > p",function() {
....
});

cross browser issues jquery dropdown menu

Ok I made a site a while back and always had issues with the menu system is needed. Basically you click a location on a map, then it displays the list of sub locations in the dropdown menu to the right. These are always their they just chance to display based on the options class.
I have put the site at shiftera.co.uk so you can see it their.
The issue first.
1) IE - The list never filters out, it displays all results all the time regardless of class.
2) Chrome - The dropdown is sometimes squashed showing 1 result and hiding the others you need to use up/down arrows to change, sometimes it shows 3, sometimes 4.
3) Firefox - The list displays in 1 long row, not like a usual dropdown.
I think the issue is more of a css problem or multitude of css problems.
An example of the map link is
Scotland
The dropdown list although not seperated is generated from the database and appears as below
<option value='AB25 1UH' class="Scotland">Aberdeen</option><option value=' WA14 4DW' class="Northwest">Altrincham</option>
As you can see, some have the space before some don't. The dropdown has the id of apick and Im using css below to hide it on load.
#apick { display: none; }
Here is the javascript to display the correct items based on map click.
//<![CDATA[
$(document).ready(function(){
$('.areaselect').on('click', function(event){
$('#apick').css('display','inline');
var id = $(this).attr('id')
$('#apick option').not('.'+id).css('display','none');
$('.'+id).css('display','inline').first().attr('selected','selected');
event.preventDefault();
});
}); //]]>
This has been driving me mad for a long time now, it seem's if i fix 1 issue another 2-3 get created. So I figured i'd try here and see if any brightspark can narrow down my issue.
Updated removing windows load as per change to main website.
The simple answer is that you are setting the style to inline. An <option> tag should not be inline, or have any style like that. The inline style i causing the problems.
Instead add the <option> tags when you need them. Store all the values in a object to add/remove them.
By the way. Remove that window load thing.
Here is the javascript fix:
$(document).ready(function()
{
var options = $('#apick option');
var values = $.map(options, function(option)
{
return option;
});
$('.areaselect')
.on('click', function()
{
var apick = $('#apick').empty();
var id = $(this).attr('id');
var newValues = $.grep(values, function(n, i)
{
return $(n).hasClass(id);
});
apick.append(newValues).show().find('option:first').attr('selected','selected');
return false;
});
});

Categories

Resources