skip to Main Content

I have the next HTML element that contain a javascript object:

<div ui-jq="easyPieChart"
     ui-options="{
                 percent: 75,
                 lineWidth: 5,
                 trackColor: '#e8eff0',
                 barColor: '#23b7e5',
                 scaleColor: false,
                 color: '#3a3f51',
                 size: 134,
                 lineCap: 'butt',
                 rotate: -90,
                 animate: 1000
                 }"
     class="easyPieChart">
</div>

How can I convert this string into array like bellow without changing HTML:

[{
  animate: 1000,
  barColor: "#23b7e5",
  color: "#3a3f51",
  lineCap: "butt",
  lineWidth: 5,
  percent: 75,
  rotate: -90,
  scaleColor: false,
  size: 134,
  trackColor: "#e8eff0"
}]

I already tried these versions:

$("[ui-jq]").each(function () {
  var self = $(this);
  // var options = eval('[' + self.attr('ui-options') + ']');
  var options = (new Function("return [" + self.attr('ui-options') + "];")());

  console.log(options);
});

But I receive an error regarding CSP:

Content Security Policy of your site blocks the use of 'eval' in JavaScript

The Content Security Policy (CSP) prevents the evaluation of arbitrary strings as JavaScript to make it more difficult for an attacker to inject unauthorized code on your site.

To solve this issue, avoid using eval(), new Function(), setTimeout([string], ...) and setInterval([string], ...) for evaluating strings.

I created a this JSFiddle to help you to show me an example faster:
https://jsfiddle.net/oqwc1j58/4/

Thank you

3

Answers


  1. If you make the attribute a data- attribute, and you make the value proper JSON, then jQuery will do that for you:

        $("[ui-jq]").each(function () {
          var self = $(this);
          var options = self.data("uiOptions");
        
          console.log(options);
        });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div ui-jq="easyPieChart"
         data-ui-options='{
                     "percent": 75,
                     "lineWidth": 5,
                     "trackColor": "#e8eff0",
                     "barColor": "#23b7e5",
                     "scaleColor": false,
                     "color": "#3a3f51",
                     "size": 134,
                     "lineCap": "butt",
                     "rotate": -90,
                     "animate": 1000
                     }'
           class="easyPieChart">
        </div>

    When jQuery sees that a data- attribute value can be parsed as valid JSON, it does that implicitly and returns the resulting value when you load it via .data(). Note that the camel-case version of the name (I think) should be used, but jQuery might work with either version. Note also that you leave off the "data-" prefix.

    Login or Signup to reply.
  2. This is kind of janky but you can parse the HTML yourself and create the array you’re looking for:

    // From https://stackoverflow.com/a/72773057/378779
    const sortObjectByKeys = (object, asc = true) => Object.fromEntries(
      Object.entries(object).sort(([k1], [k2]) => k1 < k2 ^ !asc ? -1 : 1),
    )
    
    $("[ui-jq]").each(function () {
      let options = $(this).attr('ui-options').replace('{', '').replace('}', '').split('n')
    
      let o = {}
      options.filter(function(option) { return ! option.match(/^s*$/) }).forEach(function(option){
          option = option.trim().replace(/,$/, '')
          let a = option.split(/: /)
          o[a[0]] = a[1].replace("'", '')
      })
      console.log(sortObjectByKeys(o))
    });
    </script>
    <script src="https://code.jquery.com/jquery-3.6.3.js" integrity="sha256-nQLuAZGRRcILA+6dMBOvcRh5Pe310sBpanc6+QBmyVM=" crossorigin="anonymous"></script>
    
    <div ui-jq="easyPieChart"
         ui-options="{
                     percent: 75,
                     lineWidth: 5,
                     trackColor: '#e8eff0',
                     barColor: '#23b7e5',
                     scaleColor: false,
                     color: '#3a3f51',
                     size: 134,
                     lineCap: 'butt',
                     rotate: -90,
                     animate: 1000
                     }"
         class="easyPieChart">
    </div>
    Login or Signup to reply.
  3. You can use JSON.parse():

    const opts=$("[ui-jq]").get().map(el=>Object.fromEntries(Object.entries(JSON.parse(el.getAttribute('ui-options').replaceAll("'",'"').replace(/(w+)(?=s*:)/g,'"$1"'))).sort(([a],[b])=>a.localeCompare(b))));
    console.log(opts);
    <script src="https://code.jquery.com/jquery-3.6.3.js" integrity="sha256-nQLuAZGRRcILA+6dMBOvcRh5Pe310sBpanc6+QBmyVM=" crossorigin="anonymous"></script>
    
    <div ui-jq="easyPieChart"
         ui-options="{
                     percent: 75,
                     lineWidth: 5,
                     trackColor: '#e8eff0',
                     barColor: '#23b7e5',
                     scaleColor: false,
                     color: '#3a3f51',
                     size: 134,
                     lineCap: 'butt',
                     rotate: -90,
                     animate: 1000
                     }"
         class="easyPieChart">
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search