Get dynamic state radiobutton in function - javascript

I am learning js, and I have a question that has confused me a little, I made a wrapper for the radiobutton, it is displayed in a modal window, and I want to transfer the value of the variable radiobutton to another function, tried it through var radioValue = $("input[name='radio']:checked").val();, but it retains the value that was when the page was loaded
$('input:radio[name=radio]').on('change', function () {
radioValue = $("input[name='radio']:checked").val();
});
(function(w,d,u,b){w['Bitrix24FormObject']=b;w[b] = w[b] || function(){arguments[0].ref=u;
(w[b].forms=w[b].forms||[]).push(arguments[0])};
if(w[b]['forms']) return;
var s=d.createElement('script');s.async=1;s.src=u+'?'+(1*new Date());
var h=d.getElementsByTagName('script')[0];h.parentNode.insertBefore(s,h);
})(window,document,'https://bistropechat.bitrix24.ru/bitrix/js/crm/form_loader.js','b24form');
b24form({"id":"5","lang":"ru","sec":"uwp5dl","type":"button","click":"", "presets": {"my_cookie1": "ValueChecked: " + radioValue }});

Related

How to check/uncheck checkbox based on localStorage state

I'm trying to persist checkbox state in a HTML (Flask/Jinja2) template using just html and CSS, but I've running into strange behavior where even though localStorage saves the state correctly, state is always set as true on load. I've looked up a ton of answers and have been stuck for a couple hours and I don't understand it isn't working:
HTML:
<input id="returnHeatmapsHtmlCheckbox"
type="checkbox" name="returnHeatmapsHtml" onclick="saveCheckboxState(this)" />
JS:
<script type="text/javascript">
window.onload = onPageLoad();
function onPageLoad (){
document.getElementById("returnHeatmapsHtmlCheckbox").checked = localStorage.getItem("returnHeatmapsHtmlCheckbox");
}
// <!-- Persist checkboxes -->
function saveCheckboxState(e){
var id = e.id
var val = e.checked
console.log("Saved value ID: " + id + ","+ val)
localStorage.setItem(id,val)
console.log("Loaded value ID: " + localStorage.getItem(id,val))
console.log(getSavedCheckboxState("returnHeatmapsHtmlCheckbox"))
}
function getSavedCheckboxState(v){
const default_dict = {
"returnHeatmapsHtmlCheckbox": false
};
if (!localStorage.getItem(v)) {
return default_dict[v];// return false by default.
};
return localStorage.getItem(v);
}
</script>
Any help would be greatly appreciated, thank you !
I reviewed your code and took the liberty to refactor some excerpts, I tried to keep it as similar as possible to what you did, you can see the result below.
HTML:
<input id="myCheckbox" type="checkbox" name="myCheckbox" />
JS:
// get the checkbox element
const myCheckbox = document.querySelector('#myCheckbox')
// responsible for setting a value in localStorage
// following the "checked" state
const setStorageState = (e) => {
const { id, checked } = e.target
localStorage.setItem(id, checked)
}
// responsible for searching and converting to Boolean
// the value set in localStorage
const getStorageState = (storageName) => {
return localStorage.getItem(storageName) === 'true'
}
// responsible for changing the state of your checkbox
const setCheckboxStateOnLoad = () => {
myCheckbox.checked = getStorageState('myCheckbox')
}
// calls the function "setStorageState" every time
// the user clicks on his checkbox
myCheckbox.addEventListener('click', setStorageState)
// calls the "setCheckboxStateOnLoad" function
// after the DOM content is loaded
document.addEventListener('DOMContentLoaded', setCheckboxStateOnLoad)
Hope it helps and sorry for the bad english :)

Is there a way to catch an onchange trigger with a focusout by a button click?

The scenario is this modal window:
The inputs 2, 3 and 4 with an .on('change', function () {}); makes an AJAX call to a specified controller, that update the recod values and reload the value 1.
So the right, but not functional way is to:
click the input 1 and set the value
focusout it by clicking outside the input
AJAX reload value 1 updated
click input 2 and set the value
focus out it by clicking outside the input
AJAX reload value 1 updated
The user click confirm that call another controller that make some checks and change the status of an object (from Draft to Confirmed)
The problem
If I try this way:
click the input 1 and set the value
focusout it by clicking outside the input
AJAX reload value 1 updated
click input 2 and set the value
Click confirm button that call another controller and trigger the input change
Now, with this way the problem occurs because the confirm method doesn't receive yet the update from last onchange trigger and the check is not correct.
Is there a way to manage multiple AJAX from different triggers like onchange and onclick?
Something like if the below onclick is triggered:
// Trigger for button confirm inside timesheet sheet modal
$(document).on('click', 'button.js_confirm_timesheet_sheet', function (ev) {
var $button = $(this);
var wizard_id = $button.data()['wizardId'];
var sheet_id = $button.data()['sheetId'];
var values = {
'wizard_id': wizard_id,
'sheet_id': sheet_id,
};
confirm_sheet_distribution_hours(values);
});
Check if the click come from an input focus out, if yes trigger the onchange first and after the onclick
Maybe this solution can be a bad way to do this.
Little, triggers recap:
The inputs have an onchange trigger that writes data to backend object with an AJAX call that recompute values and return the new one
The confirm button check if everything is ok with an AJAX call and change the backend object status
The other workaround maybe can be to declare an object that keeps track of each changed input boxes and clear it on each AJAX success return.
Something like:
var changedData = {};
function update_wizard_data_and_modal(values, $input_elem, event) {
changedData[key] = $input_elem;
ajax.jsonRpc("/my/controller/path", "call", values)
.then(function (new_modal_values) {
$input_elem.removeClass('input-value-error');
if (!jQuery.isEmptyObject(new_modal_values)) {
if (new_modal_values.error_msg) {
var $content = $(new_modal_values.error_msg);
$content.modal({
backdrop: 'static',
keyboard: false
});
$content.appendTo('body').modal();
// Show error class
$input_elem.val('00:00');
$input_elem.addClass('input-value-error');
}
// Update the header values with hours to be distribuited
$('#header-wizard-values').html(new_modal_values.header_values);
// Update the hours to get payed available
$('.js_hours_to_get_payed').html(new_modal_values.hours_get_payed_values);
// Clear the changedData object
for (var member in changedData) delete changedData[member];
}
});
}
function confirm_sheet_distribution_hours(values) {
if jQuery.isEmptyObject(changedData){
ajax.jsonRpc("/confirm/controller/path", "call", values)
.then(function (response) {
if ('error' in response) {
//response in this case is the modal error template
$(response.error).appendTo('body').modal();
} else {
// Close modal and refresh the grid for current period
$('#modal_timesheet_sheet_confirm').modal('hide');
var sheet_item_data = {
'year': response.year,
'month': response.month,
};
update_grid_and_bars_values(sheet_item_data);
}
});
} else {
// TODO: trigger the change for element inside object and confirm
}
}
$(document).on("change", "input.distribution-input", function (ev) {
var $input = $(this);
var sheet_id = $('input[name="sheet_id"]').val();
var wiz_line_id = Number($input.attr('id').match(/\d+/)[0]);
var row_wizard_data = $input.closest('div.row').data();
var leave_type_id = row_wizard_data['leaveTypeId'];
var wizard_id = row_wizard_data['wizardId'];
var values = {
'sheet_id': Number(sheet_id),
'wizard_id': wizard_id,
'wiz_line_id': wiz_line_id,
'leave_type_id': leave_type_id,
'input_value': $input.val(),
};
var is_good_formatted = check_string_time_format($input, {});
if (is_good_formatted) {
update_wizard_data_and_modal(values, $input, ev);
}
});
// Trigger for button confirm inside timesheet sheet modal
$(document).on('click', 'button.js_confirm_timesheet_sheet', function (ev) {
ev.preventDefault();
ev.stopPropagation();
var $button = $(this);
var wizard_id = $button.data()['wizardId'];
var sheet_id = $button.data()['sheetId'];
var values = {
'wizard_id': wizard_id,
'sheet_id': sheet_id,
};
confirm_sheet_distribution_hours(values);
});
As suggested by Taplar I used a similar approach.
Here the javascript that manages the "onchange" of a wizard in the Odoo Frontend.
// Variable used for the last input changed when user click the Confirm button
var canConfirm = true;
/* Variable used for keep trace of the number of retry inside method
* confirm_sheet_distribution_hours
* */
var nr_of_try = 0;
function update_wizard_data_and_modal(values, $input_elem, event) {
if (event.type !== 'input') {
ajax.jsonRpc("/controller/path/...", "call", values)
.then(function (new_modal_values) {
canConfirm = true;
$input_elem.removeClass('input-value-error');
if (!jQuery.isEmptyObject(new_modal_values)) {
if (new_modal_values.error_msg) {
var $content = $(new_modal_values.error_msg);
$content.modal({
backdrop: 'static',
keyboard: false
});
$content.appendTo('body').modal();
// Show error class
$input_elem.val('00:00');
$input_elem.addClass('input-value-error');
}
// Update the header values with hours to be distribuited
$('#header-wizard-values').html(new_modal_values.header_values);
// Update the hours to get payed available
$('.js_hours_to_get_payed').html(new_modal_values.hours_get_payed_values);
}
});
} else {
canConfirm = false;
}
}
function set_the_amount_on_wizard($input, values, event) {
if (event.type !== 'input') {
ajax.jsonRpc("/controller/path/...", "call", values)
.then(function (response) {
canConfirm = true;
if ('error' in response) {
//response in this case is the modal error template
$(response.error).appendTo('body').modal();
// Reset input value (backend reset the TransientModel value)
$input.val('00:00')
}
});
} else {
canConfirm = false;
}
}
function confirm_sheet_distribution_hours(values) {
if (canConfirm) {
ajax.jsonRpc("/controller/patH/...", "call", values)
.then(function (response) {
if ('error' in response) {
//response in this case is the modal error template
$(response.error).appendTo('body').modal();
} else {
// Close modal and refresh the grid for current period
$('#modal_timesheet_sheet_confirm').modal('hide');
var sheet_item_data = {
'year': response.year,
'month': response.month,
};
update_grid_and_bars_values(sheet_item_data);
}
});
} else {
/*Try six times to confirm the sheet (Until the onchange doesn't write
* new values the AJAX call doesn't set canConfirm as True
* */
if (nr_of_try <= 5) {
setTimeout(function () {
nr_of_try++;
confirm_sheet_distribution_hours(values);
}, 500);
}
}
}
//Trigger that monitorate hours distribution change
$(document).on("input change", "input.distribution-input", function (ev) {
var $input = $(this);
var sheet_id = $('input[name="sheet_id"]').val();
var wiz_line_id = Number($input.attr('id').match(/\d+/)[0]);
var row_wizard_data = $input.closest('div.row').data();
var leave_type_id = row_wizard_data['leaveTypeId'];
var wizard_id = row_wizard_data['wizardId'];
var values = {
'sheet_id': Number(sheet_id),
'wizard_id': wizard_id,
'wiz_line_id': wiz_line_id,
'leave_type_id': leave_type_id,
'input_value': $input.val(),
};
var is_good_formatted = check_string_time_format($input);
if (is_good_formatted) {
update_wizard_data_and_modal(values, $input, ev);
}
});
//Trigger that monitorate hours distribution change
$(document).on("input change", "input.payment-hour-input", function (ev) {
var $input = $(this);
var row_wizard_data = $input.closest('div.row').data();
var wizard_id = row_wizard_data['wizardId'];
var values = {
'wizard_id': wizard_id,
'input_value': $input.val(),
};
var is_good_formatted = check_string_time_format($input);
if (is_good_formatted) {
set_the_amount_on_wizard($input, values, ev);
}
});
// Trigger for button confirm inside timesheet sheet modal
$(document).on('click', 'button.js_confirm_timesheet_sheet', function (ev) {
var $button = $(this);
var wizard_id = $button.data()['wizardId'];
var sheet_id = $button.data()['sheetId'];
var values = {
'wizard_id': wizard_id,
'sheet_id': sheet_id,
};
// Variable used for retry sheet confirmation until canConfirm is not True
// Max repeat call is 6 times
nr_of_try = 0;
confirm_sheet_distribution_hours(values);
});
In simple words.
When the user is typing on inputs boxes the type input inside on.() set the variable canConfirm to false.
This prevents case when user changes values and click to the Confirm buttons immediately after.
In fact if the user changes some input box and immediately click "Confirm" the AJAX call starts only if the flag is true, if not the method calls it's self six times every 500 ms.
Let me know if there is some better way to doing that.
Thanks
PS: I will try a better approach with a DTO backend that clone data from model and manage updates like onchange cache.
Inspired by: https://python-3-patterns-idioms-test.readthedocs.io/en/latest/Messenger.html

Get date from weekview on Clicking the header

I use unitsview and weekview in scheduler.
I need to pass unitID(key) and date to another function, when I click header of classname: dhx_scale_bar.
I tried this code:
CODE: SELECT ALL
function showTitle(a) {
alert(a);
debugger;
var mode = scheduler.getState().mode;
var myDate = scheduler.getState().date;
alert(myDate);
});
if (mode == "units")
{
var hh= scheduler.getState().date;
alert(hh);
alert(mode);
}
else if (mode == "week" || mode=="decade") {
var a = document.getElementById('resourcename');
var cid = a.options[a.selectedIndex].value;
//here I get the unitId as i use list to filter_week.
var n = scheduler.getState().date;
alert(n);
// I get the same date(today's date) whenever i tried to click on any column in weekview or decade view
}
}
I attached showTitle(a) function in the main dhtlmxscheduler.js as I don't find any documentation to attach events on header. Please help.
You can use getActionData API
var unit = scheduler.getActionData(e).section;
where e - native html click event object

How to remove null from my Javascript

So, here's my script:
$(function () {
// define this here because we're changing the ID
var $twitter = $('twitter');
// bind to select inside iframe
$('#iframe').on('load', function () {
$(this).contents().find('#cds').change(function () {
var selectVal = $(this).val();
url = 'https://twitter.com/intent/tweet?button_hashtag=stream&text=Just enjoying ' + selectVal + ' on';
$twitter.attr("id", url);
}).change(); // trigger change to get initial value
});
});
Basically, it takes the selected value from my select box, and outputs it into a twitter link. The problem is, when nothing is selected, it outputs "null", and I was wondering if there was a way to detect this, and echo something else.
Try this:
var selectVal = $(this).val() || 'default value';

jquery cookie script only remembers checkboxes and not radio buttons

I have a js script that helps me create a cookie. It saves the checked checkboxes so this value is remembered (set in the cookie). Now the problem is that it doesn't seem to work with radio buttons. When reading the js-file, I see that input type=checkboxes. So it's logical it ignores radio buttons.
How do I change this script, so it will not only check the checked checkboxes, but also the checked radio buttons?
Many thanks
My js file script:
jQuery(document).ready(function(){
new chkRemembrance();
});
function chkRemembrance(){
this.__construct();
}
chkRemembrance.prototype = {
__construct : function(){
this.chk = this.fetchData(); // initialise array to store the checkboxes
this.init();
},
init : function(){
// first initialise all checkboxes that are checked
for(c in this.chk){
$("input[type=checkbox]#" + c).attr('checked', this.chk[c]);
}
// now make sure we fetch the checkbox events
var o = this;
$("input[type=checkbox]").change(function(){
o.saveData(this.id, this.checked);
})
},
fetchData : function(){
var r = {};
if ($.cookie('chk')){
r = JSON.parse($.cookie('chk'));
}
return r;
},
saveData : function(id,status){
this.chk[id] = status;
$.cookie('chk', JSON.stringify(this.chk));
}
}
It looks like you should just be able to add in the radio buttons and it will work.
Change this:
$("input[type=checkbox]#" + c).attr('checked', this.chk[c]);
To this:
$("input[type=checkbox]#" + c + ", input[type=radio]#" + c).attr('checked', this.chk[c]);
And change this:
$("input[type=checkbox]").change(function(){...});
To this:
$("input[type=checkbox], input[type=radio]").change(function(){...});

Categories