Ive spent several hours trying to resolve an issue with very limited experience with jQuery which is not helping me.
I am wanting to search a database for a list of results using a few input fields and then a submit button, when you click submit the values are passed to a .php script which returns the results and these are displayed in a table within a div container which works perfect.
Each record is then displayed in its own row within the table, with columns for different data.
record number name town etc
What i want is for the record number to be a click link of some kind, which when clicked, it then passes that value and does a different mysql request displaying that unique records data in more detail in a different div container. This is the part i cant get to work as i believe its something to do with BINDING, or the .ON which i dont really know anything or understand how it works, as my experience is very limited.
I have provided some sample code which consists of two files, jQuery.php and db.php, db.php is just simulating a database lookup for now (crude i know), to make it easier to show my code and what i am trying to do.
if you run jQuery.php and either enter a town (sheffield,rotherham) followed by click "get data" you get a refined list of results, if you just click get data you get all the results, you will see each results as a 4 dig ID Number, what i want to happen here is when you click that number it then loads just that record in a different div container, but its not working due to the dynamic content as i have read but don't understand.
You will see i have made an example of the reference number 1005 at the top of the page, and if you click on this, it loads that unique record fine, but i just can't get it to work with the ones in the table.
jquery.php
<script type="text/javascript" src="https://ajax.microsoft.com/ajax/jQuery/jquery-1.4.2.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$(".click").click(function() {
var recordid = $(this).attr("id");
$('#2').load("db.php?id=" +recordid);
});
$("#get").click(function() {
var town = $("#town").val();
$('#1').load("db.php?town="+town
);
});
});
</script>
OUTSIDE OF DYNAMIC HTML RECORD ID : - <a class = 'click' id = '1005'>1005</a><br>
<br>
Town <input type="textbox" id="town" ><br>
<button id="get">Get Data</button>
<br>
----<br>
*<div id="1" name='records_all'></div>
----<br>
*<div id="2" name='record_unique'></div>
----<br>
db.php ( crude code to simulate a db lookup, just for purpose of this problem )
<?php
$id = $_GET['id'];
$town = $_GET['town'];
echo "<pre>";
$data[]= array('id' => '1001', 'town' => 'sheffield', 'street' => 'national av', 'name' => 'neil');
$data[]= array('id' => '1002', 'town' => 'rotherham', 'street' => 'maple drive', 'name' => 'steve');
$data[]= array('id' => '1003', 'town' => 'leeds', 'street' => 'poplar drive', 'name' => 'john');
$data[]= array('id' => '1004', 'town' => 'rotherham', 'street' => 'exchange st', 'name' => 'claire');
$data[]= array('id' => '1005', 'town' => 'sheffield', 'street' => 'main street', 'name' => 'sarah');
$data[]= array('id' => '1006', 'town' => 'rotherham', 'street' => 'holderness rd', 'name' => 'jo');
if ($id) {
foreach ((array)$data as $key => $value) {
if ($data[$key]['id'] == $id) {
echo $data[$key]['id']."<br>";
echo $data[$key]['name']."<br>";
echo $data[$key]['street']."<br>";
echo $data[$key]['town']."<br>";
}
}
} else {
if ($town) {
foreach ((array)$data as $key => $value) {
if ($data[$key]['town'] == $town) {
$link = "<a class = 'click' id = '{$data[$key]['id']}'>{$data[$key]['id']}</a>";
echo "{$link} {$data[$key]['town']} {$data[$key]['name']}<br>";
}
}
} else {
foreach ((array)$data as $key => $value) {
$link = "<a class = 'click' id = '{$data[$key]['id']}'>{$data[$key]['id']}</a>";
echo "{$link} {$data[$key]['town']} {$data[$key]['name']}<br>";
}
}
}
You need to use event delegation to solve this issue. Look at the jQuery docs for .on here under the "Direct and delegated events" section
Try something like
$('#1').on('click', '.click', function() {
var recordid = $(this).attr("id");
$('#2').load("db.php?id=" +recordid);
});
This will work as long as the #1 element is in the DOM when the jQuery event bindings are run. Essentially you're binding the click event to the #1 element instead of having to bind it to elements after loading them in. The jQuery docs do a good job of explaining this.
If the elements are not in the DOM at the time of their jQuery selection then the events will not be added with the way you wrote your code. However alternatively you can write your code like this
$(document).ready(function() {
$(document).on('click', '.click', function() { //this is the only thing that changed
var recordid = $(this).attr("id");
$('#2').load("db.php?id=" +recordid);
});
$("#get").click(function() {
var town = $("#town").val();
$('#1').load("db.php?town="+town
);
});
});
This code should completely replace your javascript. It creates a live listener for all future elements in the document with the class click.
Related
I have this syntax to provde a series of checkboxes. This works fine, however no matter what syntax I use to get radios I get nothing, just a blank space.
I've tried 'type' => 'radio', and tried 'type' => 'radiogroup'.
This what I'm using now:
array(
'type' => 'checkbox',
"holder" => "div",
"class" => "",
"heading" => __("Choose your cheese topping", 'rbm_menu_item'),
'param_name' => 'cheesbox',
'value' => array( 'Cheddar'=>'Chedder', 'Gouda'=>' Gouda', 'Bleu'=>' Bleu'),
"description" => __("<br /><hr class='gduo'>", 'rbm_menu_item')
),
Any ideas? Is there a different way to get radios instead of checkboxes?
if you are using visual composer (WPBakery Page Builder) try this:
vc_add_shortcode_param( 'simple_radio', 'xyz_function' );
function xyz_function($param, $value){
if(!empty($value)){
$hval = $value;
}
else{
$hval = '';
}
$ret = '<input type="hidden" value="'.$hval.'" id="xyz'.$param['param_name'].'" name="'.$param['param_name'].'" class="wpb_vc_param_value wpb-input">';
foreach($param['value'] as $key => $p){
if($value==$p){
$checked = ' checked="checked"';
}
else{
$checked = '';
}
$ret.='<div><input type="radio" name="xyz'.$param['param_name'].'" id="'.$param['param_name'].$p.'" value="'.$p.'" class="xyz-vc-radio'.$param['param_name'].'" style="width:auto; margin-right:5px;"'.$checked.'> <label for="'.$param['param_name'].$p.'">'.$key.'</label></div>';
}
$ret.='<script>
jQuery(".xyz-vc-radio'.$param['param_name'].'").change(function(){
var s = jQuery(this).val();
jQuery("#xyz'.$param['param_name'].'").val(s);
});
</script>';
return $ret;
}
I believe that this code, having done some Googling and searching through documentation, is from Visual Composer for WordPress.
It looks like this is an array to be passed to vc_map()'s params key to add your shortcode to the Visual Composer content elements list.
Looking through the vc_map documentation, it looks as if no form of radio buttons exist within Visual Composer, unfortunately.
You could create your own param type but this seems beyond the scope of this answer. Do feel free to comment if you'd like me to go into more detail or ask another question. Hope this helps!
I have already tried this : yii2 dependent autocomplete widget
but i don't know why it's not working.
here my html with script:
<?= $form->field($model, 'lbt_holder_type')->dropDownList(['prompt' => '--- Select Holder Type ---', 'S' => 'Student', 'E' => 'Employee'],
['onChange' => 'JS: var value = (this.value);
if(value == "S"){$(#libraryborrowtransaction-name).autoComplete({source: '. $s_data.');}
if(value == "E"){$(#libraryborrowtransaction-name).autoComplete({source: '. $e_data.');}
'])?>
Autocomplete:
<?= $form->field($model, 'name')->widget(\yii\jui\AutoComplete::classname(), [
'options' => ['class' => 'form-control', 'placeholder' => 'Enter Name/ID'],
'clientOptions' => [
'source' => $s_data,
'autoFill' => true,
'minLength' => '1',
'select' => new yii\web\JsExpression("function( event, ui ) {
$('#libraryborrowtransaction-lbt_holder_id').val(ui.item.id);
}")
],
])?>
i want to change autocomplete source according to dropdownlist value, if S then load $s_data else load $e_data.
Any help with this. Thanks.
Here's my data,
$s_data = (new \yii\db\Query())
->select(["CONCAT(stu_unique_id,' - ',stu_first_name,' ',stu_last_name) as value","CONCAT(stu_unique_id,' - ',stu_first_name,' ',stu_last_name) as label","s_info.stu_info_stu_master_id as id"])
->from('stu_master stu')
->join('join','stu_info s_info','s_info.stu_info_id = stu_master_stu_info_id')
->where('is_status = 0')
->all();
and,
$e_data = (new \yii\db\Query())
->select(["CONCAT(emp_unique_id, ' - ',emp_first_name,' ',emp_last_name) as value","info.emp_info_emp_master_id as id"])
->from('emp_master emp')
->join('join', 'emp_info info', 'info.emp_info_id = emp_info_emp_master_id')
->where('is_status = 0')
->all();
Well, I've added your code snippets to my test yii2 environment to test what's wrong. So there are some problems with your code:
[
'onChange' =>
'JS: var value = (this.value);
if(value == "S"){$(#libraryborrowtransaction-name).
autoComplete({source: '. $s_data.');}
if(value == "E"){$(#libraryborrowtransaction-name).
autoComplete({source: '. $e_data.');}
']
First of all I noticed what yii apply some escaping for quotation mark symbols for your "S" and "E", and your code in browser looks like "S".
Next, jui autocomplete plugin adds a property to jquery prototype with name "autocomplete" but not "autoComplete". As for as js is case sensitive, this two names looks different for it.
So my solution was to move all js from onchange property to separate js script, as it shown below (for testing purposes you can add it right in your yii view file where you use code provided in your question)
<script>
function holderTypeChangeHandler(ev) {
var value = (this.value);
if(value == 'S'){
$('#libraryborrowtransaction-name').autocomplete({source: ' . $s_data . '});
}
if(value == 'E'){
$('#libraryborrowtransaction-name').autocomplete({source: ' . $e_data . '});
}
}
window.onload = function(){
$('#libraryborrowtransaction-lbt_holder_type').on('change', holderTypeChangeHandler);
};
</script>
And paste name of this new event handler to your dropdownList's onchange property like this:
['onChange' => 'holderTypeChangeHandler']
UPDATE: ---------------------
Since Yii2 Autocomplete based on JQuery UI autocomplete widget and Yii2 Autocomplete clientOptions contains settings for JUI autocomplete widget, then we can refer to JUI API docs for explanation of the source option. As you can see, this option can be a string (in this case it used as URI to JSON data), a function or an js array of data or js array of objects.
In your question you are using \yii\db\Query to fetch some data from db with help of method all(), which returns an array of data. So finally you need to convert the array of data which you get with \yii\db\Query->all to js array of objects. To do it, use php json functions, particulary for your case you need to use json_encode() function:
// Let's say this is a result of your query to db with use of `\yii\db\Query->...->all();`
$some_array = [
[
"value" => "Val 1",
"label" => "Label 1",
"id" => 1
],
[
"value" => "Val 2",
"label" => "Label 2",
"id" => 2
]
]
// Just convert it to json string
$s_data = json_encode($some_array);
...
// When concat this json string as a value of source attribute for Yii Autocomplete
$('#libraryborrowtransaction-name').autocomplete({source: <?= $s_data ?> });
The same if for your $e_data. Just pay attention, your get your data from db with PHP, but use it with JS, so php array needs to be converted to a string presentation js array of objects, and this conversion you can do with json_encode.
I am making a gridview in yii and my problem is that if i click select all checkbox and i go to next grid then again i click on select all after that i should get 20 values. but i am getting only 10 values which is getting from current grid. how can i get all selected checkbox value in my controller?
here is my view
<form action="<?php echo Yii::app()->createAbsoluteUrl("emails/getEmails"); ?>" method="post">
<?php
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'professional-master-grid',
'dataProvider'=>$model->search($status),
'filter'=>$model,
'selectableRows' => 2,
'afterAjaxUpdate' => "function(id,data){
$('.select-on-check').each(function(){
if(globalselected.indexOf($(this).val()) < 0){
$(this).prop('checked',false);
}else{
$(this).prop('checked',true);
}
});
}",
'beforeAjaxUpdate' => "function(id,data){
if(typeof globalselected == 'undefined') {
globalselected = [];
}
selected = $('.select-on-check:checked').map(function(i) {
return $(this).val();
}).get();//.join(',');
notselected = $('.select-on-check:not(:checked)').map(function(i) {
return $(this).val();
}).get();//.join(',');
for(i=0; i < selected.length; i++){
if(globalselected.indexOf(selected[i]) < 0){
globalselected.push(selected[i]);
}
}
for(i=0; i < notselected.length; i++){
if(globalselected.indexOf(notselected[i]) >= 0)
globalselected.splice(globalselected.indexOf(notselected[i]), 1);
}
}",
'columns'=>array(
/*'id',*/
array(
'header'=>'SN.',
'value'=>'$this->grid->dataProvider->pagination->currentPage * $this->grid->dataProvider->pagination->pageSize + ($row+1)',
),
array(
'class' => 'CCheckBoxColumn',
'selectableRows' => 2,
'checkBoxHtmlOptions' => array(
'name' => 'nos[]','class'=>'select-on-check','id'=>'example-check-boxes',
'type'=>'raw'
),
'value'=>'$data->id',
),
array(
'header'=>'Center name',
'value'=>'urldecode($data->center_name)',
'name'=>'center_name',
'sortable'=>FALSE,
),
array(
'header'=>'Fitness Center Type',
'value'=>'#$data->getRelated("fitnesscenter")->fitnesscenter_type',
'name'=>'fitnesscenter',
'sortable'=>FALSE,
),
array(
'header'=>'City',
'value'=>'#$data->getRelated("city_id")->city_name',
'name'=>'city_id',
'sortable'=>FALSE,
),
array(
'header'=>'Locality',
'value'=>'#$data->getRelated("locality")->locality',
'name'=>'locality',
'sortable'=>FALSE,
),
),
));
?>
<input type="submit" class="btn btn-primary" id="submit" value="submit" />
</form>
this is my controller
var_dump($_POST['nos']);
Why do you want to keep selected data between pages? I personally don't like that but anyways.
I see that you did a javascript implementation that uses a variable where it keeps all the selected ids.
I can see it saves the ids before ajax updating (before changing page) and that it also restores the already selected ones when coming back to the previous page.
But you might be missing to bind a event on clicking any of the checkboxes to also add them to this javascript variable. I would put the code in beforeAjaxUpdate to a separate js function outside. Then call it from here and also call it in click event of every checkbox. Hmm I think with only calling it from the click event would be enough.
Also I can see that selectableRows is set to 2, should be removed I guess.
And finally, I would create a hidden field named "globalselected" and after every time you alter the globalselected js array I would convert it toString and put it as value of the hidden field.
Then in the controller you would look for $_POST['globalselected'].
I have an array of PHP with customer data. I will modify this values in jQuery. Then O would like to submit the changed values with an Id (cashup_id) to the server from jquery. Please see the PHP array below. Please help. Thanks.
$Cashups = array(
array(
'cashup_id' => 146456,
'display_time' => 'Wed 16th Mar, 9:55pm',
'terminal_name' => 'Bar 1',
'calculated_cash' => 389.20,
'actual_cash' => 374.6,
'calculated_tenders_total' => 1,551.01,
'actual_tenders_total' => 1,551.01
),
array(
'cashup_id' => 146457,
'display_time' => 'Wed 16th Mar, 9:56pm',
'terminal_name' => 'Bar 2',
'calculated_cash' => 493.3,
'actual_cash' => 493.3,
'calculated_other' => 1509.84,
'actual_other' => 1509.84
)
);
#Powtac see the JS code.
jQuery(function($) {
$(".Cashups").delegate("td:eq(3) > a", "click", function(event) {
var a, parent, input, doneLink, b, i, eq, c, d;
var eq = $(this).parent().children("a").index(this);
// The `a` has been clicked; cancel the action as
// we're handling it
event.preventDefault();
event.stopPropagation();
// Remember it and its parent
a = $(this);
parent = a.parent();
// Insert an input in front of it, along with a done link
// because blur can be problematic
input = $("<input type='text' size='10'>");
input.insertBefore(a);
input.blur(doneHandler);
doneLink = $("<a href='#'>done</a>");
doneLink.insertBefore(a);
doneLink.click(doneHandler);
// Put the text of the link in the input
input.val(a.text());
// Temporarily detach the link from the DOM to get it
// out of the way
a.detach();
// Give the input focus, then wait for it to blur
input[0].focus();
// Our "done" handler
function doneHandler() {
// Replace the content of the original link with
// the updated content
a.text(input.val());
b = a.text();
//c = b;
alert(b);
$.get('js_test.php?b=' + b, function (data) {
$('.Cashups td a').eq(3).html(b);
});
I have two combos; provinces and cities.
I would like to change cities value when the province combo value changes. Here is my code
<div class="cities form">
<?php
$v = $ajax->remoteFunction(array('url' => '/cities/','update' => 'divcity'));
print $form-> input('Province.province_id', array('type' => 'select', 'options'=> $provinces, 'onChange' => $v));
?>
<div id="divcity">
<?php
echo $form->input('Cities.cities_name');
?>
</div>
Every time I change province combo, it call cities/index.ctp. anybody want to help?
really thank for your help
wawan
The 'url' => '/cities/' is calling the default index action of the cities controller.
This automatically renders the cities/index.ctp view.
Have you included the RequestHandler component in the cities controller?
This can be used to detect Ajax requests and then render a different view.
You need to first include the RequestHandler Component at the top of the CitiesController, then write a function to list cities, optionally requiring a Province's id.
I think you'll end up having something like this:
<?php
// In the view
$v = $ajax->remoteFunction(array('url' => '/cities/list','update' => 'divcity'));
print $form-> input('Province.province_id', array('type' => 'select', 'options'=> $provinces, 'onChange' => $v));
// In CitiesController
function list($province_id = null) {
// use $this->City->find('list', array('fields'=>array('City.id', 'City.name')))
// to generate a list of cities, based on the providence id if required
if($this->RequestHandler->isAjax()) {
$this->layout = 'ajax';
$this->render();
}
} ?>