1

I want to create a simple script that changes LESS variables and print the CSS output in a div.

this is my HTML

<input type="text" id="choose-color" onchange="ModifyColorsInLess()">
<button onclick="writeCSS()">aggiorna</button>
<div id="lesscode"></div>

This is my js

function writeCSS(){
  var lessCode = '';
  var xmlhttp = new XMLHttpRequest();
  xmlhttp.onreadystatechange = function(){
    if(xmlhttp.status === 200 && xmlhttp.readyState === 4){
      lessCode = xmlhttp.responseText;
      new(less.Parser)().parse(lessCode, function (e, tree) {
        document.getElementById('lesscode').innerHTML =   tree.toCSS().replace(/\n/g,"<br>");
      });

    }
  };
  xmlhttp.open("GET","css/styles.less",true);
  xmlhttp.send();
}

function ModifyColorsInLess() {
  less.modifyVars(
    {
      '@colore-body': $("#choose-color").val()
    }
  );
}

The script prints CSS code correctly, but if i insert a new color value in the input type="text" and call the writeCSS function, it doesn't print my variable edit. I think the problem is that "modifyvar" does not change the file "styles.less", so when I call the function writeCSS() does not detect changes made. is there a way to print the css dynamically detecting changes made with modifyvar?

TylerH
  • 20,799
  • 66
  • 75
  • 101
Ali Fumagalli
  • 239
  • 1
  • 2
  • 10
  • In you snippet the `modifyVars` option should be passed to the `parse` function ([see for example](https://github.com/less/less.js/blob/v1.7.5/dist/less-1.7.5.js#L7652)). `modifyVars` of the global `less` object applies only to those less files this global `less` automatically evaluates on page load. `new(less.Parser)()` object is actually a *new* parser object that inherits nothing from document's global `less`. – seven-phases-max Apr 03 '15 at 18:40
  • I'm new in less.js ... how could I rewrite my script using your suggestions? – Ali Fumagalli Apr 03 '15 at 18:49
  • Something [like this](https://gist.github.com/seven-phases-max/a34b07f7acd403c129de#file-29437697-js-L9) probably (non optimized). I did not actually test if that works (I just do not have any Less 1.x sandboxes around since I've switched to v2.x a while ago)). – seven-phases-max Apr 03 '15 at 19:05

1 Answers1

0

update When you allow the compiled styles are directly applied on your page, you can simply call `modifyVars as follows:

<!DOCTYPE html>
<html>
<head>
<title>Less Example</title>
<script>
less = {
    env: "development"
}    
</script>
<link rel="stylesheet/less" type="text/css" href="t.less">
<script src="//cdnjs.cloudflare.com/ajax/libs/less.js/2.5.0/less.min.js"></script>
<script>

    function writeCSS(){
        less.modifyVars({
          'colore-body': document.getElementById('choose-color').value
        });  
   }        


</script>   
</head> 
<body>
<input type="text" id="choose-color">
<button onclick="writeCSS()">aggiorna</button>
<div id="lesscode"></div>
</body>
</html>

Demo: http://plnkr.co/14MIt4gGCrMyXjgwCsoc

end update

Based on How to show the compiled css from a .less file in the browser?, How to update variables in .less file dynamically using AngularJS and Less: Passing option when using programmatically (via API) (you should also read: http://lesscss.org/usage/#programmatic-usage) you should be able to use the code like that shown below:

<!DOCTYPE html>
<html>
<head>
<title>Less Example</title>
<script>
less = {
    env: "development"
}    
</script>
<script src="//cdnjs.cloudflare.com/ajax/libs/less.js/2.5.0/less.min.js"></script>
<script>

    function writeCSS(){
    var lessCode = '';
    var xmlhttp = new XMLHttpRequest();

    xmlhttp.onreadystatechange = function(){
      if(xmlhttp.status == 200 && xmlhttp.readyState == 4){
        var options = {}
        options['modifyVars'] = {'colore-body' : document.getElementById('choose-color').value}     
        lessCode = xmlhttp.responseText;
        less.render(lessCode, options, function (error, output) {
        if(!error) {
        document.getElementById('lesscode').innerHTML = output.css;
        }
        else document.getElementById('lesscode').innerHTML = '<span style="color:red">' + error + '</span>';
        });

      }
    };
    xmlhttp.open("GET","styles.less",true);
    xmlhttp.send();
    }
</script>   
</head> 
<body>
<input type="text" id="choose-color">
<button onclick="writeCSS()">aggiorna</button>
<div id="lesscode"></div>
</body>
</html>

demo: http://plnkr.co/YbdtOwOeQPC1k9Vq4ZBv

And finally based on Force Cache-Control: no-cache in Chrome via XMLHttpRequest on F5 reload you can prevent caching of your source file with the following code:

xmlhttp.open("GET","t.less?_=" + new Date().getTime(),true);  

In the above the env: "development" setting prevents your source files from caching. To clear the cache otherwise, you should call less.refresh(true) before your less.render call.

i have another little problem, if in my less file there is a reference to another less file like this(@import "another.less") script doesn't work.

Make sure that another.less in the above is in the same folder as your styles.less file. Notice that import (when using less in browser) are read with a XMLHttpRequest too. So your imported files should be readable by browser and their paths should be relative to the styles.less file. Also see http://lesscss.org/usage/#using-less-in-the-browser-relativeurls

Community
  • 1
  • 1
Bass Jobsen
  • 48,736
  • 16
  • 143
  • 224
  • great! thank you so much!!! i have another little problem, if in my less file there is a reference to another less file like this(@import "another.less") script doesn't work. with the inspector web i see an error message like this (failed to resource file). if i use one single file .less script works very good... is there any explanation? – Ali Fumagalli Apr 05 '15 at 15:09
  • the paths are correct... with mozilla i receive this warning : "A request synchronous XMLHttpRequest on the main thread is deprecated because of the negative effects on the user experience. For more information see http://xhr.spec.whatwg.org/" maybe it is the problem... – Ali Fumagalli Apr 06 '15 at 11:41
  • i doe not think that is the reason not reaching your files, also see https://github.com/less/less.js/issues/2384 – Bass Jobsen Apr 06 '15 at 18:13