How to refresh kartik grid view periodically in yii2 - yii2

I having a yii2 page with ticket information. Example can be seen here
https://github.com/kartik-v/yii2-dynagrid/issues/97
I would like to be able to refresh the page periodically or when a records change or when a new has been added.
I have tried something like this but it does not work by some reason
$js = '$("#pageReload").on("pjax:end", function() {
$.pjax.reload({container:".inbox"}); //Reload GridView
});';
$this->registerJs($js, $this::POS_READY);
$js2 = 'function refresh() {
$.pjax.reload({container:"#dynagrid-1",timeout: 10000});
};
refresh();';
$this->registerJs($js2, $this::POS_READY);
$.pjax.reload({container: '#idGridView'});
$.pjax.reload({container: '#pjax-container', timeout: 2000});
$script = <<< JS
$.pjax.reload({container: '#av_list-1-pjax', timeout: 2000});
//JS;
$this->registerJs($script);

this is my solution to refresh the grid every minute
setInterval(
function refresh()
{
$.pjax.reload({
container:'#task-grid',
timeout:60000,
})
},10000);

Inspect element then get the container of the gridview. It should look something like this <div id="w0-pjax"> - yours might be different. In this case, w0-pjax is the id of the container.
then we can just write the following...
$.pjax.reload({container:'#w0-pjax'});

Related

How to refresh html automatically with time I setup?

I know the syntax for refreshing every xx second
<meta http-equiv="refresh" content="xx">
But I want to refresh page at the time that I setup. For example, I want to refresh at 09:00:00, 09:01:00, 09:02:00, 09:03:00...Refresh at every minute and 00 second, what should I do??
Thank for your help.
HTML can't do this; you'll either need to set the Refresh header based on the current time or use JavaScript to reload the page. This answer focuses on the JavaScript approach.
You'll need to check the time every second and refresh if it matches your requirements:
<script>
setInterval(() => {
if (new Date().getSeconds() === 0) location.reload();
}, 1000);
</script>
But there's no guarantee this will run every second, and if the :00 second is missed, the page won't reload for at least a minute. A more robust solution saves the current minute (in a closure) and reloads when it changes:
<script>
setInterval((() => {
const lastMinute = new Date().getMinutes();
return () => {
const newMinute = new Date().getMinutes();
if (newMinute !== lastMinute) location.reload();
}
})(), 1000);
</script>
Try something like this?
$(document).ready(function () {
var timeset = 10;
setInterval(function() {
location.reload();
}, timeset);
});
You need document.ready to run once the DOM is ready, see here: https://learn.jquery.com/using-jquery-core/document-ready/
You need to setInterval to repeatedly call a function: https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval
You need reload to reload the current document: https://www.w3schools.com/jsref/met_loc_reload.asp
This may require some extra tweaking / research into jQuery & other optimisations. Let me know if you have any questions!
NOTE: This uses jQuery, so you will need to include jQuery as a script on your page / in your solution: https://www.w3schools.com/jquery/jquery_get_started.asp
Use javascript but if you aware of it just use it on html
<body onload="setInterval(function(){
alert(); // also change this to location.reload(); to refresh it
},2000);"> // change 2000ms to 60000ms i put 2s to show but
test
</body>

how to detect div value (Django rendered) change with MutationObserver

I am rendering a value from django backend to frontend, and I am trying to detect the div value change with MutationObserver. Below is my current code:
MutationObserver part:
window.addEventListener('load', function () {
var element = document.getElementById('myTaskList');
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
var observer = new MutationObserver(myFunction);
observer.observe(element, {
childList: true
});
function myFunction() {
console.log("this is a trial")
console.log(element);
console.log(element.innerHTML);
}
// setTimeout(function(){
// element.innerHTML = 'Hello World!';
// }, 1000);
//
// setTimeout(function(){
// element.innerHTML = 'Hello Space!';
// }, 2000);
});
html part:
<div hidden id="myTaskList">{{resultList | safe}}</div>
I am rendering a string "dummyValue" to the div, but just don't see the value from the console.log() statements inside function.
this works well when I uncomment the setTimeout functions though.
Thanks for any help on why MutationObserver won't detect the rendered div value
I finally figured out the reason. Hope this might be helpful for people having similar issues in the future.
So, basically I was using my Django form submit button to do two actions at one time:
1. submit data to the view and process the data in the view;
2. trigger another function with the click action through
Ajax.
The second action was blocked by the first action, and I was only able to get result from action 1.
My solution: I modified action 1 to use Ajax as well. As I mentioned above, I originally used the Django form to submit data. I trigger action 2 inside the success function of action 1. Everything is working well now.

How to send a single request through p:commandButton inside p:dialog? [duplicate]

I have following jQuery code to prevent double clicking a button. It works fine. I am using Page_ClientValidate() to ensure that the double click is prevented only if the page is valid. [If there are validation errors the flag should not be set as there is no postback to server started]
Is there a better method to prevent the second click on the button before the page loads back?
Can we set the flag isOperationInProgress = yesIndicator only if the page is causing a postback to server? Is there a suitable event for it that will be called before the user can click on the button for the second time?
Note: I am looking for a solution that won't require any new API
Note: This question is not a duplicate. Here I am trying to avoid the use of Page_ClientValidate(). Also I am looking for an event where I can move the code so that I need not use Page_ClientValidate()
Note: No ajax involved in my scenario. The ASP.Net form will be submitted to server synchronously. The button click event in javascript is only for preventing double click. The form submission is synchronous using ASP.Net.
Present Code
$(document).ready(function () {
var noIndicator = 'No';
var yesIndicator = 'Yes';
var isOperationInProgress = 'No';
$('.applicationButton').click(function (e) {
// Prevent button from double click
var isPageValid = Page_ClientValidate();
if (isPageValid) {
if (isOperationInProgress == noIndicator) {
isOperationInProgress = yesIndicator;
} else {
e.preventDefault();
}
}
});
});
References:
Validator causes improper behavior for double click check
Whether to use Page_IsValid or Page_ClientValidate() (for Client Side Events)
Note by #Peter Ivan in the above references:
calling Page_ClientValidate() repeatedly may cause the page to be too obtrusive (multiple alerts etc.).
I found this solution that is simple and worked for me:
<form ...>
<input ...>
<button ... onclick="this.disabled=true;this.value='Submitting...'; this.form.submit();">
</form>
This solution was found in:
Original solution
JS provides an easy solution by using the event properties:
$('selector').click(function(event) {
if(!event.detail || event.detail == 1){//activate on first click only to avoid hiding again on multiple clicks
// code here. // It will execute only once on multiple clicks
}
});
disable the button on click, enable it after the operation completes
$(document).ready(function () {
$("#btn").on("click", function() {
$(this).attr("disabled", "disabled");
doWork(); //this method contains your logic
});
});
function doWork() {
alert("doing work");
//actually this function will do something and when processing is done the button is enabled by removing the 'disabled' attribute
//I use setTimeout so you can see the button can only be clicked once, and can't be clicked again while work is being done
setTimeout('$("#btn").removeAttr("disabled")', 1500);
}
working example
I modified the solution by #Kalyani and so far it's been working beautifully!
$('selector').click(function(event) {
if(!event.detail || event.detail == 1){ return true; }
else { return false; }
});
Disable pointer events in the first line of your callback, and then resume them on the last line.
element.on('click', function() {
element.css('pointer-events', 'none');
//do all of your stuff
element.css('pointer-events', 'auto');
};
After hours of searching i fixed it in this way:
old_timestamp = null;
$('#productivity_table').on('click', function(event) {
// code executed at first load
// not working if you press too many clicks, it waits 1 second
if(old_timestamp == null || old_timestamp + 1000 < event.timeStamp)
{
// write the code / slide / fade / whatever
old_timestamp = event.timeStamp;
}
});
you can use jQuery's [one][1] :
.one( events [, data ], handler ) Returns: jQuery
Description: Attach a handler to an event for the elements. The handler is executed at most once per element per event type.
see examples:
using jQuery: https://codepen.io/loicjaouen/pen/RwweLVx
// add an even listener that will run only once
$("#click_here_button").one("click", once_callback);
using count,
clickcount++;
if (clickcount == 1) {}
After coming back again clickcount set to zero.
May be this will help and give the desired functionality :
$('#disable').on('click', function(){
$('#disable').attr("disabled", true);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="disable">Disable Me!</button>
<p>Hello</p>
We can use on and off click for preventing Multiple clicks. i tried it to my application and it's working as expected.
$(document).ready(function () {
$("#disable").on('click', function () {
$(this).off('click');
// enter code here
});
})
This should work for you:
$(document).ready(function () {
$('.applicationButton').click(function (e) {
var btn = $(this),
isPageValid = Page_ClientValidate(); // cache state of page validation
if (!isPageValid) {
// page isn't valid, block form submission
e.preventDefault();
}
// disable the button only if the page is valid.
// when the postback returns, the button will be re-enabled by default
btn.prop('disabled', isPageValid);
return isPageValid;
});
});
Please note that you should also take steps server-side to prevent double-posts as not every visitor to your site will be polite enough to visit it with a browser (let alone a JavaScript-enabled browser).
The absolute best way I've found is to immediately disable the button when clicked:
$('#myButton').click(function() {
$('#myButton').prop('disabled', true);
});
And re-enable it when needed, for example:
validation failed
error while processing the form data by the server, then after an error response using jQuery
Another way to avoid a quick double-click is to use the native JavaScript function ondblclick, but in this case it doesn't work if the submit form works through jQuery.
One way you do this is set a counter and if number exceeds the certain number return false.
easy as this.
var mybutton_counter=0;
$("#mybutton").on('click', function(e){
if (mybutton_counter>0){return false;} //you can set the number to any
//your call
mybutton_counter++; //incremental
});
make sure, if statement is on top of your call.
If you are doing a full round-trip post-back, you can just make the button disappear. If there are validation errors, the button will be visible again upon reload of the page.
First set add a style to your button:
<h:commandButton id="SaveBtn" value="Save"
styleClass="hideOnClick"
actionListener="#{someBean.saveAction()}"/>
Then make it hide when clicked.
$(document).ready(function() {
$(".hideOnClick").click(function(e) {
$(e.toElement).hide();
});
});
Just copy paste this code in your script and edit #button1 with your button id and it will resolve your issue.
<script type="text/javascript">
$(document).ready(function(){
$("#button1").submit(function() {
$(this).submit(function() {
return false;
});
return true;
});
});
</script
Plain JavaScript:
Set an attribute to the element being interacted
Remove the attribute after a timeout
If the element has the attribute, do nothing
const throttleInput = document.querySelector('button');
throttleInput.onclick = function() {
if (!throttleInput.hasAttribute('data-prevent-double-click')) {
throttleInput.setAttribute('data-prevent-double-click', true);
throttleInput.setAttribute('disabled', true);
document.body.append("Foo!");
}
setTimeout(function() {
throttleInput.removeAttribute('disabled');
throttleInput.removeAttribute('data-prevent-double-click');
}, 3000);
}
<button>Click to add "Foo"!</button>
We also set the button to .disabled=true. I added the HTML Command input with type hidden to identify if the transaction has been added by the Computer Server to the Database.
Example HTML and PHP Commands:
<button onclick="myAddFunction(<?php echo $value['patient_id'];?>)" id="addButtonId">ADD</button>
<input type="hidden" id="hasPatientInListParam" value="<?php echo $hasPatientInListParamValue;?>">
Example Javascript Command:
function myAddFunction(patientId) {
document.getElementById("addButtonId").disabled=true;
var hasPatientInList = document.getElementById("hasPatientInListParam").value;
if (hasPatientInList) {
alert("Only one (1) patient in each List.");
return;
}
window.location.href = "webAddress/addTransaction/"+patientId; //reloads page
}
After reloading the page, the computer auto-sets the button to .disabled=false. At present, these actions prevent the multiple clicks problem in our case.
I hope these help you too.
Thank you.
One way I found that works is using bootstrap css to display a modal window with a spinner on it. This way nothing in the background can be clicked. Just need to make sure that you hide the modal window again after your long process completes.
so I found a simple solution, hope this helps.
all I had to do was create a counter = 0, and make the function that runs when clicked only runnable if the counter is = 0, when someone clicks the function the first line in the function sets counter = 1 and this will prevent the user from running the function multiple times when the function is done the last line of the code inside the function sets counter to 0 again
you could use a structure like this, it will execute just once:
document.getElementById('buttonID').addEventListener('click', () => {
...Do things...
},{once:true});

How can I make only the data table auto refresh after every 2 minutes

I am creating inbox mail at automatically refresh after 2 minutes, that displays new mail display in the datatable. How can refresh my datatable?
So you are using serverside processing. sth like this:
$(document).ready(function () {
var table = $('#TableID').DataTable({
"processing": true,
"serverSide": true,
//any other configuration options
"ajax": "path/to/processor"
});
you can force it auto refresh making table's ajax param to reload every 120 second:
setInterval(function () {
table.ajax.reload();
}, 120000);
Considering you're using server-side processing for the Ajax-sourced datatable, all you need to do is redraw the table after every 2 minutes.
You can use Javascript's setInterval() function
var oTable = $("#mytable").DataTable({
'serverSide': 'true'
});
After initialisation, use setInterval() to redraw the table with your desired time.
setInterval(function(){
oTable.draw();
}, 120000);
You will also need to call DataTable Object only ajax.reload() was not working for me
//Auto refresh Datatables on specified milliseconds
setInterval(function(){
$('#workitemgrid').DataTable().ajax.reload();
$('#exceptionqueuegrid').DataTable().ajax.reload();
}, 30000);

Prevent dynamic content loss on toggle

I am retrieving some data from the server and update the html contents of a div like this:
var req = new Request.JSON({
method: 'get',
url: 'index.php',
data: {},
onSuccess: function(r) {
$('my_div').set('html',r.output);
}
}
});
I wish to be able to 'toggle' the results as well and I use this:
var mySlide = new Fx.Slide('my_div');
$('toggle_link').addEvent('click', function(event){
event.stop();
mySlide.toggle();
event.stop();
});
This works only once presumably due to the fact that html contents are retrieved dynamically. Is there a way to prevent loosing the html contents from my Div and show the toggle effect?
Thanks!
To solve the problem about height, you need to set the resetHeight: true option to your Fx.Slide. Updated example here.