i have problem with my multilevel dependent select lists, i have six select lists dependent on each other and i have write a code to create dynamic lists using jquery. selects named as district, tehsil, project, center, school and user. it is working fine when i choose all options in a sequence, district-> tehsil-> project -> center -> school -> user, and when i change sequence at any level like district -> tehsil -> district( here district is parent of tehsil) after clicking on parent child tehsil not refreshed, and this problem exist in all hierarchy.... this jquery code calls 6 controller and models. those are not include here due to length of question. what should i do ?
this is my jquery code
$('#districts_id,#tehsils_id,#projects_id,#centers_id,#schools_id').on('change', function() {
//alert($("#districts_id option:selected").attr("title"));
//var parameters = {};
var parameters;
var url;
if($('#schools_id').val())
{
$("#users_id").removeAttr('disabled');
//parameters = JSON.stringify({schools_centers_id:$('#centers_id').val()});
parameters = {"users_schools_id": $('#schools_id').val(), users_gender: $('#gender').val()};
url = "<?php echo base_url();?>/BtaAdministratorUnionMembers/get_teachers_users_by_school_id";
}
else if($('#centers_id').val())
{
$("#schools_id").removeAttr('disabled');
//parameters = JSON.stringify({schools_centers_id:$('#centers_id').val()});
parameters = {"schools_centers_id": $('#centers_id').val()};
url = "<?php echo base_url();?>/BtaAdministratorUsers/get_schools_by_center_id";
}
else if($('#projects_id').val())
{
$("#centers_id").removeAttr('disabled');
//parameters = JSON.stringify({centers_probject_id:$('#projects_id').val()});
parameters = {"centers_probject_id": $('#projects_id').val()};
url = "<?php echo base_url();?>/BtaAdministratorUsers/get_centers_by_project_id";
}
else if($("#tehsils_id option:selected").attr("title") == 'tehsils_id')//($('#tehsils_id').val())
{
$("#projects_id").removeAttr('disabled');
//parameters = JSON.stringify({projects_tehsil_id:$('#tehsils_id').val()});
parameters = {"projects_tehsil_id": $('#tehsils_id').val()};
url = "<?php echo base_url();?>/BtaAdministratorUsers/get_projects_by_tehsil_id";
//alert(parameters + ' '+ url);
}
else if($("#districts_id option:selected").attr("title") == 'districts_id')//($('#districts_id').val())
{
$("#tehsils_id").removeAttr('disabled');
//$("#tehsils_id").empty();
//parameters = JSON.stringify({tehsils_districts_id:$('#districts_id').val()});
parameters = {"tehsils_districts_id": $('#districts_id').val()};
url = "<?php echo base_url();?>/BtaAdministratorUsers/get_tehsils_by_districts_id";
//alert(parameters + ' '+ url);
}
$.ajax({
type: "GET",
url: url,
data:parameters,
//contentType: "application/json;charset=utf-8",
dataType: 'json',
success: function(data){
//alert(data);
//alert(JSON.stringify(data));
if($('#schools_id').val())
{
//alert(JSON.stringify(data));
$('#users_id').empty();
$('#users_id').append("<option value=''>Select Teacher....</option>");
$.each(data,function(key,value){
$('#users_id').append('<option value="'+value.users_id+'">'+value.users_firstname_users_lastname+'</option>');
});
}
else if($('#centers_id').val())
{
//alert(JSON.stringify(data));
$('#schools_id').empty();
$('#schools_id').append("<option value=''>Select School....</option>");
$.each(data,function(key,value){
$('#schools_id').append('<option value="'+value.schools_id+'">'+value.schools_name+'</option>');
});
}
else if($('#projects_id').val())
{
//alert(JSON.stringify(data));
$('#centers_id').empty();
$('#centers_id').append("<option value=''>Select Center....</option>");
$.each(data,function(key,value){
$('#centers_id').append('<option value="'+value.centers_id+'">'+value.centers_schoolName+'</option>');
});
}
else if($("#tehsils_id option:selected").attr("title") == 'tehsils_id')//($('#tehsils_id').val())
{
//alert(JSON.stringify(data));
$('#projects_id').empty();
$('#projects_id').append("<option value=''>Select Project....</option>");
$.each(data,function(key,value){
$('#projects_id').append('<option value="'+value.projects_id+'">'+value.projects_name+'</option>');
});
}
else if($("#districts_id option:selected").attr("title") == 'districts_id')//($('#districts_id').val())
{
//clearDropDown($('select'), 5);
$('#tehsils_id').empty();
$('#tehsils_id').append("<option value='' title=tehsils_id>Select Tehsils....</option>");
$.each(data,function(key,value){
$('#tehsils_id').append('<option value="'+value.tehsils_id+'" title=tehsils_id>'+value.tehsils_name+'</option>');
});
}
},
error: function(data){
alert(JSON.stringify(data));
//console.log(data);
}
});
});
In each level you have to remove all next options when a top level option is changed and the set the next level again e.g in school level:
$('#schools_id').nextAll("select").each(function(){
$(this).find('option').remove();
})
// Then set again the next level
I used nextAll assuming that selects are siblings. elsewhere you have to use propper selector
With all of your if else statements organized from the most specific to least specific, fiddling with a parent input triggers the event handler but is caught by the else statement for its child.
Use separate event handlers for all six inputs based on the one you are interacting with rather than checking for values alone, and your logic will work morelike you planned.
You'll even be able to more easily handle the case where the user is jumping back a few levels and you should reset/disable a few selects.
Related
Hello guys i am trying to build a chat with Jquery , php , ajax and mysql
the problem that i am facing since few days is that when i get the value of the last message its keep getting append to the div what i want is to append the last message only once , and append again if there is a new message here is my ajax call
var chat = "";
$.ajax({
url: "php/gt_user.php",
type: "get",
success: function (result) {
var gtUser = $.parseJSON(result);
$.each(gtUser, function (idx, obj) {
var usrApp = "<span><i class='fa fa-user-circle-o' aria-hidden='true'></i>";
usrApp += "<p class='usr-name'>" + obj.Tables_in_chat + "</p></span>";
$('.userarea').append(usrApp);
}); // here i get all the username who sent a message and print them on a div
$('.userarea span').on('click', function () {
$('.msgarea').html("");
var usrName = $(this).text();
$('#usrname').text(usrName);
setInterval(function () {
$.ajax({
url: "php/admin_msg.php",
type: "post",
data: {
name: usrName
},
success: function (result) {
var lastmsg = result;
function appedn() {
var usrMsg = "<div class='usr-msg'><i class='fa fa-user-circle-o' aria-hidden='true'></i>";
usrMsg += "<span><p>" + lastmsg + "</p></span></div>";
$('.msgarea').append(usrMsg);
}
if (chat !== result) {
appedn();
} else {
chat = result;
}
}
});
}, 2000);
});
}
});
the respanse from php/admin_msg.php is working and i got the last message sucessfully the problem is that this script keep adding the same message to the message area , and what i want is to added the message only once if there is a new one
You need to somehow identify last message that is already appended to your html the best would be some id sent from server. So your message div should containt some data-id attribute, and then when you ask for next message get last children of $('.msgarea') element, read it data-id and compare with current one.
Another thing I would recommend to moving to some view library or framework, react, angular, vue or whatever. It gets complicated when you want to manage such features with pure jQuery.
i was finally able to fix the problem after 1 day of struggle so will post the answear here just in case it will help some one else facing the same issue
the part where i had to get all the username table from database i move it to my HTML and used a few line of php to echo the result like this(each user name has his own table)
// show all the user name that sent a message
$result = $con->query("show tables from chat");
while($row = mysqli_fetch_assoc($result)){
echo "<span><i class='fa fa-user-circle-o' aria-hidden='true'></i><p class='usr-name'>".$row['Tables_in_chat']."</p></span>";
}
then on my jquery script i moved the function that check for the last message every 2sec outside the click event so my Jquery script look more cleaner now
/* get the user name and added it to the header of the message box */
$('.userarea span').on('click', function () {
$('.msgarea').html("");
var usrName = $(this).text();
$('#usrname').text(usrName);
});
var chatdata = "";
/* check for new message and append the message area if there is a new one */
setInterval(function () {
var usrName = $('#usrname').text();
$.ajax({
url: "php/admin_msg.php",
type: "post",
data: {
name: usrName
},
success: function (result) {
function appedn() {
var usrMsg = "<div class='usr-msg'><i class='fa fa-user-circle-o' aria-hidden='true'></i>";
usrMsg += "<span><p>" + result + "</p></span></div>";
$('.msgarea').append(usrMsg);
}
if (chatdata !== result) {
appedn();
chatdata = result;
}
}
});
}, 2000);
my website has an option of country like for different country the website layout is different. it is running on the basis of sessions if session is not set the user will be redirected to index to select a country then will be redirected from the page where he originally came from. here's the code
my session_check_client.php file that is included in every file except index
<?php
session_start();
if(!isset($_SESSION['country']))
{
$actual_link = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
header("location:index.php?return_uri=$actual_link");
}
?>
now what happens is when i go back to home page i wanna check whether this requested has some return parameter or just user has visited he website for the first time. there are two button for two countries of which i am showing the code.
function canada(){
$.ajax({
type: 'post',
url: 'ajax_country.php?country=canada',
success: function (data) {
var $_GET = <?php echo json_encode($_GET);?>;
if($_GET){
//window.location.href=$_GET['return_uri'];
alert($_GET['return_uri']);
}
else {
window.location.href = "home.php";
}
}
});
}
function us(){
$.ajax({
type: 'post',
url: 'ajax_country.php?country=us',
success: function (data) {
var $_GET = <?php echo json_encode($_GET);?>;
if($_GET){
//window.location.href=$_GET['return_uri'];
alert($_GET['return_uri']);
}
else {
window.location.href = "home.php";
}
}
});
}
now the problem is when i am alerting the value of $_GET['return_uri'] it is giving me a false value
e.g my return_uri value is http://localhost/interfold/products2.php?category=Aprons&id=57725599688 it actually shows the whole value in return_uri in index page like http://localhost/interfold/products2.php?category=Aprons&id=57725599688 but when is get the url value using javascript it is onlye giving me the value http://localhost/interfold/products2.php?category=Aprons it is missing the $ and afterwards parts!!! any recommendations?
Since you are only using super global variables, you can directly print a JS variable above the function you are describing:
var actual_link = "<?php echo "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; ?>";
function postCountry( country ){
$.ajax({
type: 'post',
url: 'ajax_country.php?country=' + country,
success: function (data) {
if(actual_link){
//window.location.href=actual_link;
alert(actual_link);
}
else {
window.location.href = "home.php";
}
}
});
}
postCountry('us');
postCountry('canada');
I have dropdown list of country suggestions and input above. When i click on one of them - AJAX should work(and it does) and add value to #msg_native. HTML:
echo '<div class="search_native"><input type="text" name="native_input" id="native"/>';
echo "<div id='output'></div></div>";
All JQUERY :
<script type="text/javascript">
$(document).ready(function() {
$("input").keyup(function(){
$array = ['usa','france','germany'];
$input_val = $("input[name='native_input']").val();
$('#output').text('')
r = new RegExp($input_val)
for (i = 0; i < $array.length; i++) {
if ($array[i].match(r)) {
$('#output').append('<p class="match">' + $array[i] + '</p>')
}
}
});
$(document).on('click', '.match', function(){
$value = $(this).text();
$('#native').val($value);
});
});
</script>
<script type="text/javascript">
$(function() {
$('#native').change(function() {
alert('cl');
$.ajax({
type: "POST",
url: "home.php",
dataType: 'json',
encode: true,
data: {native_input: $("input[name='native_input']").val()},
cache: false,
success: function(data){
alert(data);
$("#msg_native").after(data);
}});
return false;
});
});
</script>
The problem is that the value that gets posted is only what Ive typed myself, regardless on clicked element. But I want complete value- not only typed letters...so it firstly posts value and then 'finishes' the input (if clicked)
What can you practically advice to me?
data: {native_input: $value},
returns empty string
Some of this might be debatable but I put those in place for maintainability of the code and/or to match the most recent jQuery.
Only use one document ready handler (if possible)
Remove all the global objects (put var in front of them)
Use the native id when possible as fastest selector (not $("input[name='native_input']") for instance)
use this in the event handler, not the full selector (see next item)
If I enter "France" not "france" match does not work so need to case that input to equality var $input_val = $(this).val().toLowerCase();
You start with an empty field, might be good to show the match for that - simply trigger the keyup on startup to show all the array: }).trigger('keyup'); Now they are available for your clicking.
Attach the click handler on the wrapper for the "match" elements: $('#output').on('click', '.match', function() {
Use the promise form of the ajax .done(
Create a new custom event instead of the "change" on the native. We can then trigger that event as/when needed (the real issue you describe) Example: $('#native').trigger('myMatch'); and as I use it here:
trigger the event on a full match:
if (jQuery.inArray($input_val, $array) !== -1) {
$(this).trigger('myMatch');
}
Revised code:
$(document).ready(function() {
$("#native").on('keyup', function() {
var $array = ['usa', 'france', 'germany'];
var $input_val = $(this).val().toLowerCase();
$('#output').html('');
var r = new RegExp($input_val);
for (var i = 0; i < $array.length; i++) {
if ($array[i].match(r)) {
$('#output').append('<p class="match">' + $array[i] + '</p>');
}
}
// full match entered, trigger the match
if (jQuery.inArray($input_val, $array) !== -1) {
$(this).trigger('myMatch');
}
}).on('myMatch', function() {
alert('cl');
var nativeMatch = {
native_input: $("#native").val()
};
$.ajax({
type: "POST",
url: "home.php",
dataType: 'json',
encode: true,
data: nativeMatch,
cache: false
}).done(function(data) {
alert(data);
$("#msg_native").after(data);
});
return false;
}).trigger('keyup');
$('#output').on('click', '.match', function() {
var $value = $(this).text();
$('#native').val($value).trigger('myMatch');
});
});
What I want to do is, I want to display the selection that registered under accType=Acc1 in Selection. The AccInfo function is my ajax call. I would like to pass the parameter in data. The Acc_response function is a function to operate the option value. I would like to show the branchCode,accType,Code, that is registered under Acc1. How can I do that?
function AccInfo(Acc1){
$.ajax({
type:"POST",
datatype:"json",
async:true,
data:{A:Acc1},
url:AccInfo_url,
success: function(data){
Acc_response(data);
},
error: function(jqXHR, textStatus){
errorHandling(textStatus);
}
})
}
function Acc_response(data){
console.log(data);
for (var i=0;i<data.ClientInfo.length;i++)
{
var $option=$('<option />');
$option.attr('value', data.ClientInfo[i].branchCode+"|"+data.ClientInfo[i].Code+"|"+data.ClientInfo[i].accType);
$option.text(data.ClientInfo[i].accType+" (" + data.ClientInfo[i].Code+"-"+data.ClientInfo[i].branchCode+") ";
$('#Selection').append($option);
}
}
This is more usefull;
var selectedAccType = 'your account type';
//you can set this at post action to
function Acc_response(data){
data.ClientInfo.forEach(function(client) {
if(client.accType==selectedAccType){
var optionValue = client.branchCode+'|'+client.Code+'|'+client.accType;
var optionText = client.accType+'('client.Code+'-'+client.branchCode+')';
var option = '<option value="'+optionValue+'">'+optionText+'</option>';
$('#Selection').append(option);
}
});
}
This works for if you have one <select>. If you have more selects send us your html code.
I want to populate my div minimal_table through ajax onchange event based on the chosen dropdown value. The <div class="minimal_table"> is the area of my page that I want to update every time I choose a value from my dropdown form. However, after my contents load, it returns no values from my database. I have checked the value being passed in my javascript using alert but it returns a right value. I also notice that it seems like it doesn't return true in the other_function.php if(isset($val_id))line even if I already chosen a value in the dropdown. Can somebody help me point out what is the wrong of my codes and what I am lacking? Thanks a lot. Here are my codes:
my_courses.php (ajax part)
$(':input').change(function(event){
event.preventDefault();
$('.minimal_table').html('<img src="../images/loading_trans.gif" style="position:relative; margin:350px; margin-top:250px;" />');
alert($(this).val());
var val_id = $(this).val();
var postData = {'val_id':val_id};
$.ajax({
url: "../includes/other_functions.php",
async: false,
type: "POST",
data: postData,
dataType: "html",
success: function(data){
setTimeout(function(){
$('.minimal_table').html(data);
},2000);
console.log(data);
},
});
});
other_functions.php
<?php
function ajax_request_val(){
$val_id = $_POST['val_id'];
$field = "course_type";
if(isset($val_id)){
$plans = db::getTable('plan',$field,$val_id);
foreach ($plans as $plan) {
if (eventAccessLevel(null, $plan['plan_id']) != EVENT_ACCESS_NONE) {
$course_array[] = getCourseDetails(null, $plan['plan_id']);
$pid_shown[] = $plan['plan_id'];
}
}
$events = db::getTable('tbl_event',$field,$val_id);
foreach ($events as $event) {
if (!in_array($event['plan_id'], $pid_shown)) {
$event_id = $event['event_id'];
if (eventAccessLevel($event_id, null) != EVENT_ACCESS_NONE) {
$course_array[] = getCourseDetails($event_id, null);
}
}
}
return $course_array;
}
else{
$plans = db::getTable('plan');
foreach ($plans as $plan) {
if (eventAccessLevel(null, $plan['plan_id']) != EVENT_ACCESS_NONE) {
$course_array[] = getCourseDetails(null, $plan['plan_id']);
$pid_shown[] = $plan['plan_id'];
}
}
$events = db::getTable('tbl_event');
foreach ($events as $event) {
if (!in_array($event['plan_id'], $pid_shown)) {
$event_id = $event['event_id'];
if (eventAccessLevel($event_id, null) != EVENT_ACCESS_NONE) {
$course_array[] = getCourseDetails($event_id, null);
}
}
}
return $course_array;
}
}
?>
databaseconnect.php
public static function getTable($tableName,$field='',$type_id='') {
if (!self::$db) self::connect();
if(!empty($type_id)){
$tableName = self::$db->escape_string($tableName);
return self::getObjects('SELECT * FROM `' . $tableName . '` WHERE `'. $field .'` = `'. $type_id .'`;');
}
else{
$tableName = self::$db->escape_string($tableName);
return self::getObjects('SELECT * FROM `' . $tableName . '`;');
}
}
Output:
Initial load
Loading the form dropdown menu search
Choosing value from dropdown returns right value indicated by an alert
After content load (returns no value on the div mini_table)
In other_functions.php you define the function ajax_request_val().
As far as I can see, there is no call to that function within the same file, so when you call it with Ajax, you just define the function and never call it.
You make an ajax call to other_functions.php but that file only contains a function that is never called.
There are lots of ways to approach this and tidy it up a bit but to fix the problem quickly you could try putting this at the top of other_functions.php:
if(isset($_POST['ajax'])){ echo ajax_request_val(); }
and then change the data in your ajax call as follows
var postData = {val_id:val_id, ajax:1 }