Second time ajax call not working - html

This is my page code and when I click on button work just first time:
I saw question about but I couldn't solve my problem!
<html>
<head>
<title>tsee</title>
<script src="jquery.js" type="text/javascript"></script>
<script>
$(document).ready(function () {
$("#btn").click(function () {
$.ajax({
URL: "../../generate", //this read from a servlet
type: "get",
data:{
id:120
},
cache: false,
complete: function () { alert('farshid') },
success: function (data) {
$('#result').html(data);
},
error: function () {
alert('Error')
}
})
})
});
</script>
</head>
<body>
<input type="button" id="btn" value="Ajax Request" />
<div id="result">
</div>
</body>
</html>
When I click on button, my result load to div(Draw a chart in this div and Because avoid from huge code I avoid to write here) and in second time when I click on don't work.
How can I solve this problem?
And this is video for better understanding problem.(video from my run enviroment

I think you can try .on('click', function(){ // your code }) instead of simple .click function.

After looking at your video and the jsfiddle, the problem has nothing to do with the button.
If you had opened the console, you would have seen that the problem occurs when setting the options for the HighCharts plugin.
You try to change the colors from flat to gradients, but you run this code each time you try to draw a chart.
This code assumes that the initial colors are hex values but the second time you run it it is not hex (since you changed them on the first run), and this causes the plugin to crash and stop executing (and thus it never reaches the part that draws the chart)
See problematic demo: http://jsfiddle.net/dgr2ky4h/
You need to remove the HighChart color setting from that function and only run it once when you load the page.
See working demo: http://jsfiddle.net/dgr2ky4h/1/
So remove the following code from your success method
Highcharts.getOptions().colors = Highcharts.map(
Highcharts.getOptions().colors,
function (color) {
console.log(color);
return {
radialGradient: {
cx: 0.5,
cy: 0.3,
r: 0.7
},
stops: [
[0, color],
[
1,
Highcharts.Color(color)
.brighten(-0.3)
.get('rgb')] // darken
]
};
and run it out of the success only once..
<script>
$(function(){
Highcharts.getOptions().colors = Highcharts.map(
Highcharts.getOptions().colors,
function (color) {
console.log(color);
return {
radialGradient: {
cx: 0.5,
cy: 0.3,
r: 0.7
},
stops: [
[0, color],
[1, Highcharts.Color(color)
.brighten(-0.3)
.get('rgb')] // darken
]
};
});
});
</script>

could be a binding issue...
.click binds event to button as many times as you click. try
Either using $("element").on("click", function(){do stuff here});
or unbind click on button after you execute stuff...
wrong answer...Apologies

Related

How can I get the value of a radio button inside a google visualization table

I have a table that I build using a chart wrapper as follows:
var rightWrapper;
function drawVisualization() {
rightWrapper = new google.visualization.ChartWrapper({
"chartType": "Table",
'dataSourceUrl':'https://docs.google.com/spreadsheets/d/1I3N5DtdXGWFootaOCQM201K_ao2ZPWSWyw9_l7QcwQg/gviz/tq?sheet=User_my_crew&headers=1',
'containerId':'target_table_div',
'query':'SELECT A,B,C,D',
'options': { 'width': 700, 'height': 500, 'allowHtml': true }
});
google.visualization.events.addListener(rightWrapper, 'ready', onRightReady);
rightWrapper.draw();
function onRightReady() {
google.visualization.events.addListener(rightWrapper.getChart(), 'select', rightSelectionHandler);
}
function rightSelectionHandler() {
var selection = rightWrapper.getChart().getSelection();
if (selection.length == 1) {
var item = selection[0];
if (item.row != null) {
alert("selected row " + item.row);
var value = (rightWrapper.getSnapshot().getDataTable().getValue(item.row,3));
alert(value);
}
}
}
}
And in that column 3, I have html to build radio buttons. Unfortunately, the actual html is stored, and I don't seem to have a way of polling to find out which radio button is now checked (the getValue listed in the code above always shows me just the html that was used to build the radio buttons, not which one is now "checked").
Unfortunately, it appears any clicks inside that table have to be picked up with the select listener, and the select listener doesn't relay any information beyond the row and column selected. I tried building in change and click functions, and putting s around my radio buttons, too. For instance:
$("#radio").click(function(){ //also tried with .change
alert("working");
});
That never fires, even if I disable my original listener.
So, how can I know what radio button my user selected?
Note: I do need the radio buttons inside the table, as every single row of the table has its own radio buttons to provide me different information on each.
you don't need the form, you just need to wait for the chart's 'ready' event,
before assigning the change event.
see following working snippet,
select a radio to see the name and value...
google.charts.load('current', {
packages: ['controls', 'table']
}).then(function () {
var rightWrapper = new google.visualization.ChartWrapper({
chartType: 'Table',
dataSourceUrl: 'https://docs.google.com/spreadsheets/d/1I3N5DtdXGWFootaOCQM201K_ao2ZPWSWyw9_l7QcwQg/gviz/tq?sheet=User_my_crew&headers=1',
containerId: 'target_table_div',
query: 'SELECT A,B,C,D',
options: { 'width': 700, 'height': 500, 'allowHtml': true }
});
google.visualization.events.addListener(rightWrapper, 'ready', onRightReady);
rightWrapper.draw();
function onRightReady() {
$('input[type="radio"]').on('change', calcForm2);
}
});
function calcForm2(sender) {
console.log(sender.target.name, sender.target.value);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="target_table_div"></div>
I figured out something that works
I can add a form around my radio buttons with the event.preventdefault code and call a function:
<form name="myForm" onchange="event.preventDefault(); calcForm2(this);">...radiobuttons...</form>
Then in my function I do whatever I want with "this". It comes across as "name=value" so it's pretty easy to split and parse.

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 to refresh only <div> content in a web page?

The div is:
<div>
<canvas id="chart-area2" width="300" height="300"/>
</div>
how to refresh the above div every 10 seconds without reloading the page?
following is the javascript:
<script>
var pieData2 = [
{
value: <?= $pfstatetext;?>,
color:"#F7464A",
highlight: "#FF5A5E",
label: "Red :"
},
{
value: <?= $cpuusage; ?>,
color: "#46BFBD",
highlight: "#5AD3D1",
label: "Green"
},
{
value: 100,
color: "#FDB45C",
highlight: "#FFC870",
label: "Yellow"
},
{
value: 40,
color: "#949FB1",
highlight: "#A8B3C5",
label: "Grey"
},
{
value: 120,
color: "#4D5360",
highlight: "#616774",
label: "Dark Grey"
}
];
window.onload = function(){
var ctx2 = document.getElementById("chart-area2").getContext("2d");
var myPie2 = new Chart(ctx2).Pie(pieData2);
};
</script>
how can i use setInterval in the above code?.....................................................................................................
You may use that code
function refreshTheDiv(){
// Your drawing code here
window.setTimeout(refreshTheDiv,10000);
}
And replace the line // Your drawing code here with your code referencing the canvas element.
In your specific case :
(function(){
var myPie2;
window.onload = function(){
var ctx2 = document.getElementById("chart-area2").getContext("2d");
myPie2 = new Chart(ctx2).Pie(pieData2);
updateChart();
};
function updateChart()
{
$.getJson('/data.php',function(data){
// Do the update here (Seems dead : https://github.com/nnnick/Chart.js/issues/13 )
// You may deal with chartjs methods or recreate the chart:
myPie2 = new Chart(ctx2).Pie(data); // Quick and dirty solution
setTimeout(updateChart,10000);
});
}
})();
The data.php contains something like:
<?php
echo json_encode(
array(
array(
'value'=> $pfstatetext,
'color'=>"#F7464A",
'highlight'=> "#FF5A5E",
'label'=> "Red :"
),
array(
'value'=>$cpuusage,
'color'=> "#46BFBD",
'highlight'=> "#5AD3D1",
'label'=> "Green"
),
array(
value: 100,
color: "#FDB45C",
highlight: "#FFC870",
label: "Yellow"
)
//...
)
);
You must include JQuery : http://code.jquery.com/jquery-1.11.1.js
for my solution to work
ChartJS update data
If you want to update the canvas painting and you're not working with the server, use js setTimeout or setInterval (You can read about these functions here: http://www.w3schools.com/js/js_timing.asp). In the callback function that you pass to these functions you work with the canvas' context object and paint whatever you want.
If you want to update the content, like text and HTML, or if the painting is related to the server, I think you should use AJAX. AJAX enables communication after the page was loaded, so you don't have to load the whole page again. There are many tutorials for ajax, one of them is on W3schools. Also, if you work with AJAX, you should use the timing functions that I've mentioned before in order to refresh it every 10 seconds.
Another solution is to use Server-Sent Events. If you want to refresh the div in order to UPDATE the content (according to the DB, the server, etc.) so the content will be always updated, you can use this technique that follows about differences and updates, and loads them. You can read about it here : http://www.w3schools.com/html/html5_serversentevents.asp. I'm not sure if this technique is what you're looking for, it depends on what is your purpose of reloading the page, so I think the AJAX would be a great solution if the content is from the server, and the first solution is the only one which is correct if you don't work with the server.
write one function to fetch content inside div trough ajax, and write a jquery code to call the function in every 10 seconds.
For example:
function fetch_content(){
$.ajax({
url: "url for ajax page",
type: "POST",
success: function(data){
$('div').html();
}
});
}
and code to call this function every 10 seconds
setInterval(fetch_content,10000);

primefaces barchart : displaying data point on bar

how can I display data point on bar in barchart?
I don't want to use datatip or tooltip which will highlight data points only when they are moused over.
I want to display the data point always on the bar.
is there any right way to get it?
thanks.
I want exactly like this
following is my code
<p:barChart id="barChartId" value="#{myBean.myModel}"
orientation="horizontal"
stacked="true" extender="ext" animate="true" shadow="false" />
<h:outputScript>
function ext() {
this.cfg.highlighter = {
useAxesFormatters: false,
tooltipAxes: 'x'
};
this.cfg.legend = {
show: true,
location: 'ne',
placement: 'outside'
};
this.cfg.seriesDefaults = {
pointLabels : { show: true },
};
}
</h:outputScript>
here, highlighter and legend are working fine but point labels are not displaying on bar
Not sure if it will work...
Use the extender of the <p:barChart , like this:
<p:barChart value="#{myBean.myModel}" widgetVar="myBarChart" extender="my_ext"/>
<script type="text/javascript">
function my_ext() {
this.cfg.seriesDefaults = {
renderer:$.jqplot.BarRenderer,
pointLabels: {show: true}
};
this.cfg.stackSeries: true;
}
</script>
or this
<script type="text/javascript">
function my_ext() {
this.cfg.seriesDefaults = {
pointLabels: {show: true}
};
this.cfg.stackSeries: true;
}
</script>
Also take a look at the jqplot examples : Bar charts
Just in case someone doesn't crawl through the comments of the marked answer, as I didn't do in the first place.
The problem basically is not the configuration of the pointLabelselement, but rather that primefaces (as of 4.0) in its original state does not ship with the needed plugin of jqPlot included.
Therefore actually the solution is to make the needed plugin jqplot.pointLabels.min.js available. From a ticket in the bug tracker (http://code.google.com/p/primefaces/issues/detail?id=5378) I extracted, that primefaces uses jqPlot version 1.0.8.
download jqplot 1.0.8 from https://bitbucket.org/cleonello/jqplot/downloads/
add the plugin to your project (e.g. src/main/webapp/resources/jqplot-plugins)
add the plugin as script to your page (<h:outputScript library="jqplot-plugins" name="jqplot.pointLabels.min.js" />)

Click event not registering on second page

I'm using tablesorter and tablesorter.pager. Here is my code:
$(document).ready(function() {
$("#peopletable")
.tablesorter({ widthFixed: true, widgets: ['zebra'] })
.tablesorterFilter({ filterContainer: $("#people-filter-box"),
filterClearContainer: $("#people-filter-clear-button"),
filterColumns: [1, 2, 3],
filterCaseSensitive: false
})
.tablesorterPager({ container: $("#peoplepager") });
$("#peopletable tr.data").click(function() {
var personid = $(this).attr('id');
$.ajax({
type: "POST",
url: "/Search/GetDocumentsByPerson",
data: { "id": personid },
datatype: "json",
success: function(data) {
var results = eval(data);
$("#documentstable > tbody tr").remove();
$.each(results, function(key, item) {
$("#documentstable > tbody:last").append(html);
});
$("#documentstable").trigger("update");
}
});
});
});
Everything works great except when I click on the next page my button click event doesn't fire. Is this a known issue with jQuery tablesorter?
It's because the elements are updated, the ones you bound the click handler to are gone, you can use .live() to resolve this, change this:
$("#peopletable tr.data").click(function() {
To this:
$("#peopletable tr.data").live('click', function() {
Alternatively, if #peopletable isn't destroyed you can use .delegate(), like this:
$("#peopletable").delegate('tr.data', 'click', function() {
I have also faced the same kind of problem with tablesorterPager second page after using Jeditable (edit in place) plugin for some element in the tablesorterPager used table.
I have tried editing the data bind function in Jeditable as follows
original code
$(this).bind(settings.event, function(e) {
here settings.event equals to the event parameter which we are defining with options eg: click
modified code
$(this).live(settings.event, function(e) {
But.. I found the error with tablesorterPager within pages other than the first page is not because of the binding of element event.
when we are calling tablesorterPager to any table with many rows, only the first page rows of
the table is affected on the page load. so only the first page rows are called with Jeditable plugin. other rows in the other pages are not assigned with the plugin. because of this reason, the events in other pages than first page will not work.
to prevent above situation, we can add Jeditable plugin calling inside updatePageDisplay function.
eg:
function updatePageDisplay(c) {
$(".tablerowdata").each(function(){
$(this).editable("ajax/save.php", {
tooltip : "click to edit...",
data : {"selectid1":"selectval1","selectid2":"selectval2","selectid3":"selectval3"},
type : "select",
submit : "ok",
event : "click",
select : "true",
});
});
Creating a new element won't duplicate the event created with the click method wheras the live method does it.