Jquery getting new value after data attribute update - javascript

I am updating link attribute values via ajax response.but When i am again clicking the button/link getting old values instead of new value.
Below is my codes;
HTML
<div class="calendar-control"><a class="evecal-month-view-control fright next-month" href="#" data-month="2" data-year="2019">Next</a><span class="text-center month-name">January 2019</span><a class="evecal-month-view-control fright prev-month" href="#" data-month="12" data-year="2018">Previous</a></div>
And Jquery code.
jQuery(document).on('click', '.evecal-month-view-control', function(e){
e.preventDefault();
var month = jQuery(this).data('month');
var year = jQuery(this).data('year');
console.log(month);
_getMonthCalendar(month, year);
});
var _getMonthCalendar = function(m, y){
jQuery.ajax({
type: 'POST',
url: eventcaldata.ajaxurl,
data: {
action: 'ec_ajax_month_table',
year: y,
month: m,
nonce: eventcaldata.nonce,
},
beforeSend: function(){
console.log('sending...');
},
success: function(response){
jQuery('.next-month').attr( 'data-month', response.nextmonth.month );
jQuery('.next-month').attr( 'data-year', response.nextmonth.year );
jQuery('.prev-month').attr( 'data-month', response.prevmonth.month);
jQuery('.prev-month').attr( 'data-year', response.prevmonth.year);
}
});
}
First on .next-month class the data-month attribute value is 2
then it is changed to 3 after response.But When i am again clicking
that button i am getting 2 value when it should be 3

The .data() method on jQuery objects caches the value from the initial read. Subsequent call to .data() will first look in jQuery's data storage and send you that value. .attr() won't update the data storage, but will update the attribute in HTML. Use either .data() or .attr() but avoid mix and match.

Do not intermix this usage of attr() and data(). data() caches the value that it reads from the element, and does not update the attribute. So if you update with data, attr will not see it. Pick one or the other, and stick with it.

Related

How can ajax based Select2 pre-population be formatted?

We've found several examples of pre-populating selected option for Select2, however none of them we could find deal with formatted list and selection options. We have a JS fiddle at https://jsfiddle.net/gpsx62de/26/ that illustrates the issue. In that fiddle, you can type and L or whatever into the select search and the data is returned, the list is formatted, and if you select something, the selection is formatted.
However if you click the button in that JS Fiddle which is intended to simulate pre-population per https://select2.org/programmatic-control/add-select-clear-items#preselecting-options-in-an-remotely-sourced-ajax-select2 the data is returned (you can uncomment the console.log to see it), but the formatted selection shows undefined for the intended values. Does anyone know of a way to get the formatted values for pre-populated data to display correctly?
// Set up the Select2 control
$('#mySelect2').select2({
ajax: {
url: '/api/students'
}
});
// Fetch the preselected item, and add to the control
var studentSelect = $('#mySelect2');
$.ajax({
type: 'GET',
url: '/api/students/s/' + studentId
}).then(function (data) {
// create the option and append to Select2
var option = new Option(data.full_name, data.id, true, true); //**** DOES IT MATTER WHAT IS PASSED HERE BECAUSE WE ARE NOT DISPLAY THE OPTION TEXT?? ***
studentSelect.append(option).trigger('change');
// manually trigger the `select2:select` event
studentSelect.trigger({
type: 'select2:select',
params: {
data: data //**** THIS DOES NOT SEEM TO SUPPORT FORMATTED SELECTIONS, SO HOW CAN THIS BE DONE? ***
}
});
});
The problem is in format_selection function. The format of the object it receives depends on how it was created. When you use new Option(text, value) it receives only the properties of this Option object, not your original object containing all user info.
A workaround is to check of either possible values in the fuction:
function format_selection(obj) {
let name = obj.name || obj.element.text;
let email = obj.email || obj.element.email;
return $(`<div><b>${name}</b></div><div>(${email})</div>`);
}
For this to work you should append the de property on you Option object:
var option = new Option(data.name, data.id, true, true);
option.email = data.email;
$('#sel').append(option).trigger('change');
The problem, in https://jsfiddle.net/gpsx62de/26/ is with the
function format_selection(obj) {
// Just add this to see the obj
console.log(obj);
return $(`<div><b>${obj.text}</b></div><div>(${obj.id})</div>`);
}
The obj object just contains the Option class data, so:
id: "1",
selected: true,
text: "Leanne Graham",
title: ""
So you have to find a way to pass "data.email" to the "format_selection" method
EDIT
This could be a solution
$('#btn').on('click', function() {
$.ajax({
type: 'GET',
url: 'https://jsonplaceholder.typicode.com/users/1'
})
.then(function(data) {
console.log(data)
// create the option and append to Select2
$('#sel').append($('<option />') // Create new <option> element
.val(data.id) // Set value
.text(data.name) // Set textContent
.prop('selected', true)
.attr('data-name', data.name) // Don't know why the .data(key, value) isn't working...
.attr('data-email', data.email))
.trigger('change');
}); //then
}); //click
And
function format_selection(obj) {
return $(`<div><b>${obj.element.dataset.name}</b></div><div>(${obj.element.dataset.email})</div>`);
}
This is the fiddle https://jsfiddle.net/947jngtu/

Reach data-attribute of select2 select

Is there a way to reach a data-attribute from within a select2?
$('select').select2({
ajax: {
url: url + '&id=' + $(this).attr('data-id')
//...
}
});
//...
<select data-id="1"></select>
<select data-id="2"></select>
<select data-id="3"></select>
To pass a custom param to your ajax url in select2, you should use the data ajax function:
$('select').select2({
ajax: {
url: "zee/base/url" // base url, no params
data: function(params) {
return {
q: params.term, // search term
id: $(this).data('id') // ta daaaa!
page: params.page
};
},
// moar ajax options
},
// moar select2 config options
})
As a general note, this inside select2 config options refers to the select2 instance (which is an object) and this inside the data function outlined above refers to the DOM element select2 was called upon, hence the jQuery wrapper$(this) has a .data() method.
Reading the document, it says that you can insert the url as a data-type in html select tag like so:
<select data-ajax--url="YOUR DESIRED URL" data-ajax--cache="true">
...
</select>
This url will override the options you have set inside of the function when calling, thus using a different one for each option you set it to in html.

Isit possible to pass value into <div data-value="" > by jquery?

This is my html code
<div data-percent="" ></div>
This is my javascript
function retrieveProgressbar(){
$.ajax({
type:"post",
url:"retrieveprogressbar.php",
data:"progressbar",
success:function(data){
$(this).data("percent").html(data);
}
});
}
retrieveProgressbar();
I need the value retrieved by ajax to be displayed in the data-percent="". I am not sure how to do that. I have another javascript that needs to use this value to execute.
Need to use .attr() method.
<div data-percent="" id="datadiv"></div>
<script>
function retrieveProgressbar() {
$.ajax({
type: "post",
url: "retrieveprogressbar.php",
data: "progressbar",
success: function (data) {
//$("#datadiv").attr("data-percent", data);
// OR
$(this).attr("data-percent", data);
}
});
}
retrieveProgressbar();
</script>
HTML:
<div data-percent=""></div>
The proper way to assign data on jquery is
var new_data_value = "I will be the new value.";
$("div").data("percent",new_data_value);
The .data() method allows us to attach data of any type to DOM elements in a way that is safe from circular references and therefore from memory leaks.
You can retrieve the data by:
var value = $( "div" ).data( "percent" );
.attr() on the other hand set/get the value of an attribute for the first element in the set of matched elements or set one or more attributes for every matched element.
It does not attach data of any type to DOM elements.
$("div").attr("data-percent",data_value);
Sources:
https://api.jquery.com/data/
http://api.jquery.com/attr/
Yep, you can use the .attr( function instead.
$(this).attr("data-percent", your_value);

Populate items into SELECT with Jquery

I'm having trouble populating a SELECT with jquery, when the user writes the zipcode or part of it, it searches the database and returns this:
{"success":1,"id":"50","street":"Central One"},{"success":1,"id":"60","street":"Central Two"}
One success for each street it finds. For a single street and using a text input I'm using this
UPDATE 1 - FULL CODE
$(document).ready( function() {
$('#zip').blur(function(){
$.ajax({
url : '../../controller/zip.php',
type : 'POST',
data: 'zip=' + $('#zip').val(),
dataType: 'json',
success: function(data){
if(data.sucesso == 1){
$('#id').val(data.id);
$('#street').val(data.street);
}
}
});
return false;
})
});
How can I change this so I can populate a select box.
Thanks
What is being passed back for a single address is a single object from which you can grab the information. When there are multiple responses you need to go through each of them and handle them.
When we look at MDN's article it shows that we need a parent <select> tag and then we need to populate the children. The process would look like this:
Find / create parent select
[Optional] Remove previous child <option> tags
Loop through responses
Create a new <option> element
Populate the <option> with the appropriate value and content
Append it to the parent <select>
Some things to be aware of, if you're clearing the previous addresses each time you get a response from the database you'll want to remove these previous <option>s. This can be done either by .empty() if there are no other children in the parent or starting with the parent <select> and removing all child <options>.
Use this for adding items to select box dynamically:
var $selectBox = $('#selectboxId');
$selectBox.empty();
$.each(data, function (idx, val) {
if (val.success) {
$selectBox.append($('<option>', {
value: val.id,
text: val.street
}));
}
});
I would not encourage to do so; you're better off using a html-templating engine like mustache or handlebars.
Doing this kind of stuff in plain JS (string concatenation) is gross. It pollutes your sourcecode.
Anyways, this would do the trick to generate the necessary HTML:
function generateHTML(data){
return data.reduce(function(o,n){
return o+"<option value='"+n.id+"'>"+n.street+"</option>";
},"");
}
Here is the Fiddle to play with. If you need to filter for success, you could add a filter()
function generateHTML(data){
return data.filter(function(x){
return !!x.success;
}).reduce(function(o,n){
return o+"<option value='"+n.id+"'>"+n.street+"</option>";
},"");
}
You could easily use $("#selectBoxId").html(generateHTML(data)) to insert it to the DOM.
To fit it into your codebase, you should add it in the success handler:
success: function(data){
function generateHTML(data){
return data.reduce(function(o,n){
return o+"<option value='"+n.id+"'>"+n.street+"</option>";
},"");
}
$("select").html(generateHTML(data))
}
For the inner workings of Array.prototype.reduce() take a look at MDN and for Array.prototype.filter()
If the JSON being returned is a list [{...}, ..., {...}], then you can use Array.forEach. Here is the success callback:
function(data) {
data.forEach(function(item) {
if (item.success) {
// use item.id and item.street
}
});
}
If you have a <select> element, then you will want to be populating it with <options>, by appending an <option> element under each successful "if" branch in the forEach.
Assuming you already have the select element on the page and the data that is coming back from the server is an array of objects, this should work:
$.ajax({
url : '../../controller/zip.php',
type : 'POST',
data: 'zip=' + $('#zip').val(),
dataType: 'json',
success: function(data) {
var $items = [];
$.each(data, function(street) {
if(data.success === 1) {
$items.push($('<option />').attr({
value: street.id
}).text(street.street));
}
});
$('#your-select-element').append($items);
}
});
Notice this isn't setting the value for one option, it is creating <option> tags for each of the response's streets and appending them to a <select> element.

How can I remove AutoNumeric formatting before submitting form?

I'm using the jQuery plugin AutoNumeric but when I submit a form, I can't remove the formatting on the fields before POST.
I tried to use $('input').autonumeric('destroy') (and other methods) but it leaves the formatting on the text fields.
How can I POST the unformatted data to the server? How can I remove the formatting? Is there an attribute for it in the initial config, or somewhere else?
I don't want to send the serialized form data to the server (with AJAX). I want to submit the form with the unformatted data like a normal HTML action.
I wrote a better, somewhat more general hack for this in jQuery
$('form').submit(function(){
var form = $(this);
$('input').each(function(i){
var self = $(this);
try{
var v = self.autoNumeric('get');
self.autoNumeric('destroy');
self.val(v);
}catch(err){
console.log("Not an autonumeric field: " + self.attr("name"));
}
});
return true;
});
This code cleans form w/ error handling on not autoNumeric values.
With newer versions you can use the option:
unformatOnSubmit: true
Inside data callback you must call getString method like below:
$("#form").autosave({
callbacks: {
data: function (options, $inputs, formData) {
return $("#form").autoNumeric("getString");
},
trigger: {
method: "interval",
options: {
interval: 300000
}
},
save: {
method: "ajax",
options: {
type: "POST",
url: '/Action',
success: function (data) {
}
}
}
}
});
Use the get method.
'get' | returns un-formatted object via ".val()" or
".text()" | $(selector).autoNumeric('get');
<script type="text/javascript">
function clean(form) {
form["my_field"].value = "15";
}
</script>
<form method="post" action="submit.php" onsubmit="clean(this)">
<input type="text" name="my_field">
</form>
This will always submit "15". Now get creative :)
Mirrored raw value:
<form method="post" action="submit.php">
<input type="text" name="my_field_formatted" id="my_field_formatted">
<input type="hidden" name="my_field" id="my_field_raw">
</form>
<script type="text/javascript">
$("#my_field_formatted").change(function () {
$("#my_field").val($("#my_field_formatted").autoNumeric("get"));
});
</script>
The in submit.php ignore the value for my_field_formatted and use my_field instead.
You can always use php str_replace function
str_repalce(',','',$stringYouWantToFix);
it will remove all commas. you can cast the value to integer if necessary.
$("input.classname").autoNumeric('init',{your_options});
$('form').submit(function(){
var form=$(this);
$('form').find('input.classname').each(function(){
var self=$(this);
var v = self.autoNumeric('get');
// self.autoNumeric('destroy');
self.val(v);
});
});
classname is your input class that will init as autoNumeric
Sorry for bad English ^_^
There is another solution for integration which doesn't interfere with your client-side validation nor causes the flash of unformatted text before submission:
var input = $(selector);
var proxy = document.createElement('input');
proxy.type = 'text';
input.parent().prepend(proxy);
proxy = $(proxy);
proxy.autoNumeric('init', options);
proxy.autoNumeric('set', input.val())''
proxy.change(function () {
input.val(proxy.autoNumeric('get'));
});
You could use the getArray method (http://www.decorplanit.com/plugin/#getArrayAnchor).
$.post("myScript.php", $('#mainFormData').autoNumeric('getArray'));
I came up with this, seems like the cleanest way.
I know it's a pretty old thread but it's the first Google match, so i'll leave it here for future
$('form').on('submit', function(){
$('.curr').each(function(){
$(this).autoNumeric('update', {aSign: '', aDec: '.', aSep: ''});;
});
});
Solution for AJAX Use Case
I believe this is better answer among all of those mentioned above, as the person who wrote the question is doing AJAX. So
kindly upvote it, so that people find it easily. For non-ajax form submission, answer given by #jpaoletti is the right one.
// Get a reference to any one of the AutoNumeric element on the form to be submitted
var element = AutoNumeric.getAutoNumericElement('#modifyQuantity');
// Unformat ALL elements belonging to the form that includes above element
// Note: Do not perform following in AJAX beforeSend event, it will not work
element.formUnformat();
$.ajax({
url: "<url>",
data : {
ids : ids,
orderType : $('#modifyOrderType').val(),
// Directly use val() for all AutoNumeric fields (they will be unformatted now)
quantity : $('#modifyQuantity').val(),
price : $('#modifyPrice').val(),
triggerPrice : $('#modifyTriggerPrice').val()
}
})
.always(function( ) {
// When AJAX is finished, re-apply formatting
element.formReformat();
});
autoNumeric("getArray") no longer works.
unformatOnSubmit: true does not seem to work when form is submitted with Ajax using serializeArray().
Instead use formArrayFormatted to get the equivalent serialised data of form.serializeArray()
Just get any AutoNumeric initialised element from the form and call the method. It will serialise the entire form including non-autonumeric inputs.
$.ajax({
type: "POST",
url: url,
data: AutoNumeric.getAutoNumericElement("#anyElement").formArrayFormatted(),
)};

Categories