Here I would like to replace in the draggable slider the "," sign used for the thousands into this sign " ' " (a quote mark).
I am currently using a plugin to render the table (from a JSON file) so I cannot alter the HTML.
I am able to change the sign, in fact on page load the sign seems correct, but as soon I drag the slider the separator changes to a comma again.
I saw that the data is rendered from the Plugin with a comma in the aria-valuetext="" attribute: <div class="noUi-handle noUi-handle-upper" data-handle="1" tabindex="0" role="slider" aria-orientation="horizontal" aria-valuemin="0.0" aria-valuemax="100.0" aria-valuenow="100.0" aria-valuetext="2,290.00"><div class="noUi-tooltip">2,290.00</div></div>
I tried using this code without any results:
<script>
window.onload = function(){
var div = document.querySelectorAll('.noUi-tooltip');
div.forEach(function(r) {
var text = r.textContent;
var output = text.replace(/[,|]/g, "'");
r.innerHTML = output;
});
}
</script>
What am I writing wrong?
I am using WordPress and the wpdatatables plugin.
I'm not sure about the plugin you've used for your slider but perhaps you can try this for now:
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.type == "attributes") {
var parentEl = document.getElementsByClassName('noUi-handle-upper');
var childEl = parentEl.childNodes[0];
childEl.innerHTML = childEl.innerHTML.replace(',', '\'');
}
});
});
observer.observe(document.getElementsByClassName('noUi-handle-upper')[0], {
attributes: true,
});
It's using MutationObserver which is not supported by older browsers. You can read more about it at https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver.
This is because you modify the string just in the beginning (on load).
This is why the code works in the beginning but doesn't work later, because it runs once and then stops.
I don't know how to use WordPress or sliders, but I'd advise you to use an 'on value changed' command, so the text will change to whatever you want it to each time the slider's value is changed.
I will post this now but I'll review your code and will try to update this with more exact information later.
Related
I am working on a photo editing page. The goal is for users to be able to adjust parameters such as hue, saturation, brightness by uploading pictures and then editing them using range sliders. In order to ensure the program worked well on mobile browsers I decided to use the rangeslider.js library. After getting an initial slider up and working I decided to try more advanced designs. I found this design online and like it. My goal now is to have multiple slider each which displays its value like the linked slider. I am having trouble achieving this. To keep things simple I am currently formatting my slider using the standard css from rangeslider.js. I am able to create a single slider which behaves like the one in the linked design, but now I want to generalize this to multiple sliders, which is where I am having trouble. In the single design the code relevant to creating the rangeslider is
//custom slider javascript
var $element = $('input[type="range"]');
var $handle;
$element
.rangeslider({
polyfill: false,
onInit: function() {
$handle = $('.rangeslider__handle', this.$range);
updateHandle($handle[0], this.value);
}
})
.on('input', function() {
updateHandle($handle[0], this.value);
});
function updateHandle(el, val) {
el.textContent = " " + "$" + val + " ";
}
$(document).ready(function(){
//when slider changes, hide start message
$("input").on("change", function() {
$("#helper").fadeOut("slow");
});
//promo-box
$("#js-promo-box").hide();
$("#promo-link").on("click", function(){
$("#js-promo-box").slideToggle();
return false;
});
});
If I leave this function unchanged when declaring multiple range sliders in the html code then there are no errors but only the range input which was declared last will have a label displaying its value. But all of the sliders will be able to change this value. I narrowed this problem down to the fact that there is only a single $handle variable. To fix this I created the code below
<script>
//custom slider javascript
var $element = $('input[type="range"]'); // Gets all the elements of type range
var $handle = new Array($element.length);
console.log($element);
for(i=0; i<$element.length;i++){
console.log($element[i]);
var $temp = $($element[i]);
$temp.rangeslider({
polyfill: false,
onInit: function() {
$handle[i] = $('.rangeslider__handle', this.$range);
updateHandle($handle[i][0], this.value);
}
})
.on('input',function() {
updateHandle($handle[i][0], this.value);
});
}
function updateHandle(el, val) {
console.log(el);
el.textContent = " " + "$" + val + " ";
}
$(document).ready(function(){
//when slider changes, hide start message
$("input").on("change", function() {
$("#helper").fadeOut("slow");
});
//promo-box
$("#js-promo-box").hide();
$("#promo-link").on("click", function(){
$("#js-promo-box").slideToggle();
return false;
});
});
</script>
Now $handler is an array with as many entries as there are range inputs. When run everything initializes fine and the initial values of the sliders are displayed as expected. Despite this when I change the slider I get the error "Uncaught TypeError: can't access property 0, $handle[i] is undefined". This occurs in
.on('input',function() {
updateHandle($handle[i][0], this.value);
});
I do not understand why this error is occurring, especially since the values are initially displayed. Considering the only difference between the code for a single slider and multiple sliders is the $handle is now an array I believe it must have something to do with this but I am unsure where exactly the issue is.
Thank You
It turns out that this is a variable scope problem more than anything. An incredibly useful resource to explain this problem and its solution is "JavaScript Callbacks Variable Scope Problem" by Itay Grudev.
Essentially because the callback variable is created in a for loop use of the variable i (the looping variable) is not a good idea. This is because on later calls the value of i is not known to the callback function because it is outside of its scope. There are multiple ways to fix this as described by Itay Grudev. The easiest is to change
for(var i=0; i<$element.length;i++){ ...
Into
for(let i=0; i<$element.length;i++){ ...
But I believe this is not supported on all browsers. Instead what I did was create an inline closure. This allows me to create a variable within the closure which contains the value of i for a specific slider. In this way each callback can know which slider it corresponds to and react accordingly. My final code is below
for(var i=0; i<$element.length;i++){
console.log($element[i]);
var $temp = $($element[i]);
$temp.rangeslider({
polyfill: false,
onInit: function() {
//On init this is fine I don't need a separate definition of i
$handle[i] = $('.rangeslider__handle', this.$range);
updateHandle($handle[i][0], this.value);
}
})
.on('input', (function() {
var j = i;
return function() {
updateHandle($handle[j][0], this.value);
}
})() );
Now instead of calling a function to adjust the slider values this script creates a function to create a new function and then calls that function. The created function has access to variable j, which is what was missing previously
I am using Sigma.js with the cypher plugin to visualise my neo4j database. After following the simple example here https://github.com/jacomyal/sigma.js/blob/master/examples/load-neo4j-cypher-query.html , it is working well. I edited the plugin so that the graph labels displayed are the names of my neo4j nodes, however I would also like to show the other node properties when clicking on the label or node.I am quite new to JavaScript so would like to know if this is possible for a beginner like me to do and if it is where is the best place for me to start.
You have to register an event on the click or hover node.
There is an example into sigmajs for event : https://github.com/jacomyal/sigma.js/blob/master/examples/events.html
This is a short code that demonstrate how to make this. Replace the alert method by what you want.
sigma.bind('overNode', function(event) {
alert(event.data.node);
});
If you just want to discover your database, take a look at tank-browser : https://www.npmjs.com/package/tank-browser
Cheers
You have to edit Cypher plugin
First: Define var let's assume we will call it "has" at the beginning of the file.
Second: You should add ul in your html and add class to it called 'popover'
Third: Add to cypherCallback method you should add inside else if (typeof sig === 'object')
sig.graph.read(graph);
sig.bind('clickNode', function(e) {
var clicknode = e.data.node;
// empty the printed list
$('.popover').empty();
has='';
// create the tlis tof prop. from returend Object
for(var keys in clicknode.neo4j_data ){
$('.popover').append(' <li>' + keys + ' = '+ clicknode.neo4j_data[keys] + '</li>');
has+= 'n.' +keys + '="'+ clicknode.neo4j_data[keys] + '"AND ';
}
$('.popover').show();
});
sig.bind('clickStage', function(e) {
$('.popover').hide();
});
I am trying to get a link from some youtube embedded video's, in order to make some links to them, which in their place trigger a nice fancybox to watch the video in.
Getting the ID from the embedded video, and replacing it in the right link isnt the problem. It gets dirty as soon as I try to code in the loop.
The javascript I use is as following:
$('.portfolio_det iframe').each(function(i) {
var videolink = this.src.replace('http://www.youtube.com/embed/', '');
var videolink = videolink.replace('?fs=1&feature=oembed', '')
$('.portfolio_thumb .youtubeLink').each(function(i) {
$(this).attr('href', "http://www.youtube.com/watch?v=" + videolink);
});
});
The Last piece of the code retrieves the link in
Though they all get the href created on the first youtube video.
How do I set the variable to be in the loop aswell?
To make it all a bit clearer, here is a jsfiddle from the setup:
JS fiddle
You are defining var videolink twice and leaving the ; off of the end of the second one.
The second line should be:
videolink = videolink.replace('?fs=1&feature=oembed', '');
Define the variable outside the loop. Also once if you have defined a variable you dont have to put var in front of it.
var videolink;
$('.portfolio_det iframe').each(function(i) {
videolink = this.src.replace('http://www.youtube.com/embed/', '');
videolink = videolink.replace('?fs=1&feature=oembed', '')
$('.portfolio_thumb .youtubeLink').each(function(i) {
$(this).attr('href', "http://www.youtube.com/watch?v=" + videolink);
});
});
I have a strange problem with a jquery autocomplete widget.
First I have a 'select' HTML element which displays all the projects.
I also have an input element in which I can search for questionnaires which correspond to the selected project.
So I have this code : http://jsfiddle.net/AMkKX/1/
Everything works great. But my problem is when I refresh the page (with F5, not Ctrl+F5) : the previous choice of the select box is always selected so I want to change the source of the autocomplete widget (the code I show you should do that)
But the source doesn't change unless I put an alert before $('#search-questionnaire').autocomplete('option', 'source', data); :
$('#search-project').change(function () {
var data;
var val = $(this).val();
alert('val : ' + val);
if (val != '')
data = questionnairesData[val];
else
data = allQuestionnairesData;
$('#search-questionnaire').autocomplete('option', 'source', data);
});
So I don't understand. Is it a bug ?
EDIT : I can't show you the 'F5 refresh' thing with jsfiddle. If you want to test it you have to copy the code and use it in your navigator.
I haven't tested your code, but from the looks of it, this is a timing issue. I encountered this in Javascript a couple of times. To solve this, try using a setTimeout of 0ms:
Instead of
$('#search-questionnaire').autocomplete('option', 'source', data);
Try:
setTimeout(function() {
$('#search-questionnaire').autocomplete('option', 'source', data);
}, 0)
Let me know how this goes.
Hi everybody
I am using the tinymce format dropdown to apply custom styles to html elements. This is for users without html knowledge
One annoying thing for me is that when a user klicks at different styles they all get added and something like this may happen
<div class="floatleft floatright positionup positiondown">
In order to prevent this I searched for the responsible code which is in editor_template.js (compressed) but visible in editor_template_src.js
Is there maybe a way to rewrite this piece of javascript so that each applied style replaces the former?
_createStyleSelect : function(n) {
var t = this, ed = t.editor, ctrlMan = ed.controlManager, ctrl;
// Setup style select box
ctrl = ctrlMan.createListBox('styleselect', {
title : 'advanced.style_select',
onselect : function(name) {
var matches, formatNames = [];
each(ctrl.items, function(item) {
formatNames.push(item.value);
});
ed.focus();
ed.undoManager.add();
// Toggle off the current format
matches = ed.formatter.matchAll(formatNames);
if (!name || matches[0] == name)
ed.formatter.remove(matches[0]);
else
ed.formatter.apply(name);
ed.undoManager.add();
ed.nodeChanged();
return false; // No auto select
}
});
How about:
if (!name || matches[0] == name)
ed.formatter.remove(matches[0]);
else
ed.formatter.remove(matches[0]);
ed.formatter.apply(name);
Just a wild guess, haven't tried it myself.
This a lot of work to do, but it can be done.
I solved this issue writing a custom plugin and using a custom FormatterClass.
I suggest you try developing with tiny_mce_dev.js - this way you are able to track down problems to js classes.
Then you should have a look at the js-class Formatter.js and try to modify this one in order to fullfill your wishes.
The next step will be to save the mofied Formatter.js and make it part of your plugin, so that you can reset the real Formatter.js, cause i suggest not to change the tinymce core files.