Attribute options for jQuery UI datepicker
Asked Answered
D

6

17

I have this input with data-options attribute.

<input class="data" type="text" data-options="{maxDate:'0'}" />

I would like to load the datepicker using the data-options value as options. Now with the following code, doesn't work

$("input.data").each(function(){
    var dateOptions=$(this).data('options');
    $(this).datepicker(dateOptions)
});

but if I put the option on the js like in the following code, it works:

$("input.data").each(function(){
    $(this).datepicker({maxDate:'0'})
});

https://jsfiddle.net/VixedS/exfLf6o9/

If is somebody can, I would prefer an answer without eval.

Durango answered 17/12, 2015 at 13:45 Comment(6)
have you tried to do a console.log of dateOptions? What do you get?Hypocycloid
I get what I wrote {maxDate:'0'}. You can test it on the fiddle I've post.Durango
Updated the answer https://mcmap.net/q/703979/-attribute-options-for-jquery-ui-datepicker and it works fineChurchwoman
check this: jsfiddle.net/exfLf6o9/9Kessler
@Kessler I'm looking for a solution with double marks in the attribute.Durango
@Durango You can use double quotes instead of single quotes and escape the double quotes from inside the text. But i think that will be a bit confusing. jsfiddle.net/exfLf6o9/10Kessler
G
8

Jquery data automatically parses JSON strings into objects. You just have to follow the directions from jQuery.parseJson()

http://api.jquery.com/jquery.parsejson/

Changing your Options From data-options="{maxDate:'0'}" to data-options='{ "maxDate": 0 }' Works wonders

EDIT: 12/28/2015

Since in XHML you don't want to use single ' for properties, you can do the oposite and then replace the single quotes with double then parse the json response. { 'maxDate': 0 } then .replace(/'/g, '"') and use $.parseJSON()

$("input.dataWithoutOptions").each(function() {
   $(this).datepicker({
     maxDate: '0'
   })
 });

 $("input.data").each(function() {
   var dateOptions = $.parseJSON($(this).data('options').replace(/'/g, '"'));
   $(this).datepicker(dateOptions);
 });
input {
     display: block;
     margin: 10px 0 20px;
     padding: 5px;
   }
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.3/jquery-ui.min.js"></script>

This has options attr:
<input class="data" type="text" data-options="{ 'maxDate': 0 }" />This is just a date pick:
<input class="dataWithoutOptions" type="text" />

EDIT: 12/30/2015

@Lidaranis : Brings up a good point.

You can use escaped characters to avoid regex and parsing json. {&quot;maxDate&quot;:0}

$("input.dataWithoutOptions").each(function() {
  $(this).datepicker({
    maxDate: '0'
  })
});

$("input.data").each(function() {
  var dateOptions = $(this).data('options');
  $(this).datepicker(dateOptions);
});
input {
  display: block;
  margin: 10px 0 20px;
  padding: 5px;
}
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.3/jquery-ui.min.js"></script>

This has options attr:
<input class="data" type="text" data-options="{&quot;maxDate&quot;:0}" />This is just a date pick:
<input class="dataWithoutOptions" type="text" />
Gradual answered 19/12, 2015 at 17:45 Comment(3)
Sorry, but I'll never use single marks for an xHtml attribute. #243266Durango
@Neoptt, I really like your answer, but can you please fix the single and double mark problem?!Durango
I'm pretty sure that this is the simplest answer if you are using jquery. Just do a string replace the quotes and parse the json response, after that it's all downhill from there.Gradual
L
11

When you call data function, it returns string so you have to convert it to an object and then pass it to datepicker and remove curly bracket from value of data-options.

Solutions:

1- Use eval

Javascript

eval('({' + $(this).data('options') + '})')

HTML

data-options="maxDate:'0'"

2- Jquery .data and surround your data attribute value by '

Javascript

$(this).data('options')

HTML

data-options='{"maxDate":0}'

3- use plugin or write custom function(the below code is written by @allenhwkim).

Javascript

function JSONize(str) {
  return str
    // wrap keys without quote with valid double quote
    .replace(/([\$\w]+)\s*:/g, function(_, $1){return '"'+$1+'":'})    
    // replacing single quote wrapped ones to double quote 
    .replace(/'([^']+)'/g, function(_, $1){return '"'+$1+'"'})         
}

jQuery.parseJSON(JSONize($(this).data('options')));

HTML

data-options="{maxDate:'0'}"

Note: all above solutions are tested and they works.

$("input.dataWithoutOptions").each(function() {
  $(this).datepicker({
    maxDate: '0'
  })
});

$("input.data").each(function() {
  var dateOptions = eval('({' + $(this).data('options') + '})');

  console.log(typeof($(this).data('options'))); //String

  console.log(typeof(dateOptions)); //Object


  $(this).datepicker(dateOptions)
});
input {
  display: block;
  margin: 10px 0 20px;
  padding: 5px;
}
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.3/jquery-ui.min.js"></script>


This has options attr:
<input class="data" type="text" data-options="maxDate:'0'" />This is just a date pick:
<input class="dataWithoutOptions" type="text" />

Jsfiddle

Latty answered 19/12, 2015 at 17:32 Comment(4)
Your code will show the datepicker but will not apply the options. Take a look jsfiddle.net/VixedS/3ytqt9ghDurango
i have the same idea, tried the same in the jsfiddle and didn't have it to work. +1 for managing the fiddle :)Hypocycloid
@Durango See the updated answer for better understanding.Latty
@Durango Great, Good luck.Latty
G
8

Jquery data automatically parses JSON strings into objects. You just have to follow the directions from jQuery.parseJson()

http://api.jquery.com/jquery.parsejson/

Changing your Options From data-options="{maxDate:'0'}" to data-options='{ "maxDate": 0 }' Works wonders

EDIT: 12/28/2015

Since in XHML you don't want to use single ' for properties, you can do the oposite and then replace the single quotes with double then parse the json response. { 'maxDate': 0 } then .replace(/'/g, '"') and use $.parseJSON()

$("input.dataWithoutOptions").each(function() {
   $(this).datepicker({
     maxDate: '0'
   })
 });

 $("input.data").each(function() {
   var dateOptions = $.parseJSON($(this).data('options').replace(/'/g, '"'));
   $(this).datepicker(dateOptions);
 });
input {
     display: block;
     margin: 10px 0 20px;
     padding: 5px;
   }
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.3/jquery-ui.min.js"></script>

This has options attr:
<input class="data" type="text" data-options="{ 'maxDate': 0 }" />This is just a date pick:
<input class="dataWithoutOptions" type="text" />

EDIT: 12/30/2015

@Lidaranis : Brings up a good point.

You can use escaped characters to avoid regex and parsing json. {&quot;maxDate&quot;:0}

$("input.dataWithoutOptions").each(function() {
  $(this).datepicker({
    maxDate: '0'
  })
});

$("input.data").each(function() {
  var dateOptions = $(this).data('options');
  $(this).datepicker(dateOptions);
});
input {
  display: block;
  margin: 10px 0 20px;
  padding: 5px;
}
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.3/jquery-ui.min.js"></script>

This has options attr:
<input class="data" type="text" data-options="{&quot;maxDate&quot;:0}" />This is just a date pick:
<input class="dataWithoutOptions" type="text" />
Gradual answered 19/12, 2015 at 17:45 Comment(3)
Sorry, but I'll never use single marks for an xHtml attribute. #243266Durango
@Neoptt, I really like your answer, but can you please fix the single and double mark problem?!Durango
I'm pretty sure that this is the simplest answer if you are using jquery. Just do a string replace the quotes and parse the json response, after that it's all downhill from there.Gradual
A
1

the datepicker function needs an object and currently you are passing a string hence you get the error.

Audrieaudris answered 30/12, 2015 at 6:31 Comment(0)
C
0

Try this,

Option - 1

change JavaScript to

$("input.data").each(function(){
  var dateOptions=$(this).data('options');
  var options = dateOptions.split(', ');
  var obj = {};
  options.forEach(function(opt) {
      var item = opt.split(':');
      obj[item[0]] = item[1];
  });

  $(this).datepicker(obj);
});

and change html to

<input class="data" type="text" data-options="maxDate:'0'"/>

And no eval()

see the javascript fiddle https://jsfiddle.net/exfLf6o9/7/

Option - 2

JavaScript

$("input.data").each(function(){
  var dateOptions=$(this).data('options');
  dateOptions = dateOptions.substring(1,dateOptions.length-1);
  var options = dateOptions.split(', ');
  var obj = {};
  options.forEach(function(opt) {
      var item = opt.split(':');
      obj[item[0]] = item[1];
  });

  $(this).datepicker(obj);
});

and leave html as it is

see the js fiddle https://jsfiddle.net/exfLf6o9/8/

Option - 3

change html to

<input class="data" type="text" data-options='{"maxDate":"0"}' />

and in javascript

$("input.data").each(function(){
  var dateOptions=$(this).data('options');
  $(this).datepicker(dateOptions);
});

using eval() is not recommended in JavaScript

Please see the fiddle https://jsfiddle.net/exfLf6o9/5/

Churchwoman answered 21/12, 2015 at 7:16 Comment(5)
Can you fiddle your answer?Durango
fiddle added for this answer!Churchwoman
Doesn't works... check your fiddle. the maxDate 0 is today, but your fiddle shows all the future till the end of time :{Durango
Sorry, but I'll never use single marks for an xHtml attribute.Durango
added another option. Fiddles are updated and tested. Working fineChurchwoman
D
0

data() returns a string when datepicker() is expecting an object. The solution is to convert the string to an object:

$("input.data").each(function(){
    var dateOptions = $(this).data('options');
    var dateOptionsAsObject = JSON.parse(dateOptions.replace(/([\w|\-|\_]+:)/g,"\"$1\":"));
    $(this).datepicker(dateOptionsAsObject);
});
Delrio answered 30/12, 2015 at 9:44 Comment(0)
W
0

Wanted to throw out the lazy-loading technique, since no one mentioned it.

<div class="data" data-max-date="0"></div>

$.data() will automatically camelCase your data attributes and attempt to type cast. i.e. the above html attribute data will become: { maxDate: 0 }

$('.data').each(function(){
  $this = $(this);
  $this.datepicker($this.data());
});
Winson answered 19/2, 2016 at 21:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.