Dependent / Cascading Dropdown - javascript

I am using the cascading dropdown jquery plugin. ( https://github.com/dnasir/jquery-cascading-dropdown)
I have two dropdowns. 'Client' and 'Site'.
Based on which client you select, the sites list should be appropriately reduced to only show the sites for the selected client. I have setup two php scripts returnClientList.php and returnSiteList.php that successfully return json arrays with a label/value pair.
My problem is that I cannot reduce the site list, after selecting the client. The event successfully fires but I only get the full list back. As you will see, the code is using the getJSON request which i know from the manual sends a HTTP GET. Looking at the network panel of chrome reveals that there is no GET value actually being sent.
Hopefully something obvious but I am new to jquery so help appreciated.
My code:
JS
$('#edit-shift').cascadingDropdown({
selectBoxes: [
{
selector: '.clients',
source: function(request, response) {
$.getJSON('returnClientList.php', request, function(data) {
var selectOnlyOption = data.length <= 1;
response($.map(data, function(item, index) {
return {
label: item.label,
value: item.value,
selected: selectOnlyOption // Select if only option
};
}));
});
}
},
{
selector: '.sites',
requires: ['.clients'],
source: function(request, response) {
$.getJSON('returnSiteList.php', request, function(data) {
var selectOnlyOption = data.length <= 1;
response($.map(data, function(item, index) {
return {
label: item.label,
value: item.value,
selected: selectOnlyOption // Select if only option
};
}));
});
}
},
{
onChange: function(event, value, requiredValues){}
}
]
});
PHP
//this script returns a json array for use in jquery autocomplete fields for site lists...
header('Content-type: application/json');
require("connect.php");
$client_id = $_GET['?'];
//do the query for sites that are active
$sql = "SELECT * FROM site WHERE active=1 AND client_id='$client_id' ORDER BY site_name ASC";
$result = mysql_query($sql) or die('Error: ' . mysql_error());
//loop the results and create php array
while($row = mysql_fetch_array($result)){
$arr[] = array('label' => $row['site_name'], 'value' => $row['id']);
}
echo json_encode($arr);

Ended up writing my own solution to this and scrapped the plugin. Enjoy.
//dynamically returns the sites once the user chooses a client - edit/add shift form
$('.client-id').change(function () {
var selectedClient = $(this).val();
if (selectedClient != null && selectedClient != '') {
$.getJSON('returnSiteList.php', { id: selectedClient },
function (Sites) {
var siteSelect = $('.site-id');
siteSelect.empty();
$.each(Sites, function (index, site) {
siteSelect.append($('<option/>', {
value: site.value,
text: site.label
}));
});
});
}
});

Related

Ajax Post with php in jtable is returning empty data

I've been struggling with this and I don't find anyway to get this right.
I am using jtable and the thing is everything works correctly except with child elements.
I added a child table to a button so that when it opens it displays data related with the previous id.
The thing is listAction, updateAction and createAction are working okay, but when it comes to deleteAction it is not sending any information via post, so there is no way I can delete the exact row I want to.
This is the jquery (jtable) code:
asignaturas: {
title: '',
width: '5%',
create: false,
edit: false,
display: function (asignaData) {
//Create an image that will be used to open child table
var $img = $('<img src="metro/list_metro.png" style="opacity:0.4;"title="Editar Asignaturas" />');
//Open child table when user clicks the image
$img.click(function () {
$('#crudTable').jtable('openChildTable',
$img.closest('tr'),
{
title: asignaData.record.nombre + ' - Assignatures',
actions: {
listAction: 'index.php?ex=jprofesor&action=prepara&prepara=list&id=' + asignaData.record.dni,
deleteAction: 'index.php?ex=jprofesor&action=prepara&prepara=delete&id=' + asignaData.record.dni,
updateAction: 'index.php?ex=jprofesor&action=prepara&prepara=update&id=' + asignaData.record.dni,
createAction: function (postData) {
//console.log("creating from custom function...");
return $.Deferred(function ($dfd) {
$.ajax({
url: 'index.php?ex=jprofesor&action=prepara&prepara=create&id=' + asignaData.record.dni,
type: 'POST',
dataType: 'json',
data: postData,
success: function (data) {
$dfd.resolve(data);
$('#crudTable').jtable('reload');
$('.ui-dialog-titlebar-close').click();
},
error: function () {
$dfd.reject();
}
});
});
}
},
fields: {
dni: {
type: 'hidden',
defaultValue: asignaData.record.dni
},
codigo: {
title: 'Asignatura',
width: '80%',
// list: false,
options: "index.php?ex=jprofesor&action=prepara&prepara=asignaturas"
}
}
}, function (data) { //opened handler
data.childTable.jtable('load');
});
});
//Return image to show on the person row
return $img;
}
//acaba child
}
},
And this is the php code that deletes:
$query = $query." and p.dni = '".$dni."'";
$dni = $conn->real_escape_string($_GET['id']);
$codigo = $conn->real_escape_string($_POST['codigo']);
$conn->query("delete from prepara where dni = '".$dni."' and asignatura = '".$codigo."'");
retornarPrepara($conn, $query);
function retornarPrepara($conn, $query, ) {
$rs = $conn->query($query);
$num_rows = $rs->num_rows;
$rows = array();
if($rs) {
while($row = $rs->fetch_assoc())
{
$rows[] = $row;
}
$jTableResult = array();
$jTableResult['Result'] = "OK";
$jTableResult['Records'] = $rows;
$jTableResult['TotalRecordCount'] = $num_rows;
print json_encode($jTableResult);
}
}
As far as I know the code is okay, but there must be something I'm missing in jquery to send the field codigo via post, but I thought jtable did this automatically as it is doing it with the parent jtable without any problem.
I'm gonna answer my question as I finally got this to work... it was a silly mistake but at the same time it is good to be aware about it.
The thing is this a school exercise in which we received some database tables that don't have id's so I wasn't really treating the fields as if there was a primary key, anyway deleteAction only sends the key in ajax post so the only way to get it is putting key:true, into the field you want to get.
Once I added key:true, everything worked correctly.

Select2 inserts an empty text option in the dynamic list

I am using Select2 with Jquery-editable and encountering an abnormal behavior of Select2, what I am doing is displaying editable table of information using ejs template, and as user clicks on CBA opens up a select2 box which have the originally selected result, and then user can add or delete options in it, options comes from Database source, and when user selects an options it adds an empty option in database with the selected option , the array looks like this
[ "ABCD", "ONAB", "" , "BCNU" ]
I read somewhere about allowClear: true and add a placeHolder but It doesn't helped me at all. As everything is done dynamically I can't find where that empty option is added.
Code is below:
Ejs/HTML code for Select 2
<tr>
<td width="40%">Select CBA(s)</td>
<td>
<a class="cbaSelectUnit" data-emptytext="Select CBA(s)" data-original-title="Select CBA(s)" data-type="select2"></a>
</td>
Javascript for Select 2
$("a[data-name='Cba']").editable({
showbuttons: 'false',
emptytext: 'None',
display: function(values) {
var html = [];
html.push(values);
$(this).html(html);
},
select2: {
multiple: true,
allowClear: true,
placeholder: "Select CBA(s)",
ajax: {
// url is copied from data-source via x-editable option-passing mechanism
dataType: 'json',
// pass the '?format=select2' parameter to API call for the select2-specific format
data: function(term, page) {
return {
deptId: departmentId,
format: 'select2'
};
},
// transform returned results into the format used by select2
results: function(data, page) {
return {
results: data
};
}
},
// what is shown in the list
formatResult: function(cba) {
return cba.text;
},
// what will appear in the selected tag box
formatSelection: function(cba) {
return cba.text;
},
// rendering id of the values to data.value requirement for Select 2
id: function(cba) {
return cba.value;
},
// what is shown in the selected-tags box
initSelection: function(element, callback) {
var id = $(element).val(),
result = id.replace(/^,\s*$/, ',').split(",").map(function(v) {
return {
id: v,
text: v
};
});
callback(result);
}
}
});
Format in which Code is returned from the database:-
Facility.findOne({ _id: department.Facility }, function(err, facility) {
if (err) {
res.send(500, err);
} else if (!facility) {
res.send(404, 'Facility not found');
} else if (req.query.format && req.query.format === 'select2') {
var result = facility.Cba.map(function(c) {
return { value: c, text: c };
});
res.json(result);
}
});
Image showing an empty box added by itself
How Array looks after I edit
So it was just a simple syntax error, I was doing found out by myself,
I was returning cba.value as id, but the initSelection was returning
{id: v, text: v}
it should be value & text instead of id & text.
// what is shown in the selected-tags box
initSelection: function(element, callback) {
var id = $(element).val(),
result = id.replace(/^,\s*$/, ',').split(",").map(function(v) {
return {
value: v,
text: v
};
});
callback(result);
}

jTable Conditional show\hide edit and delete buttons based on owner of data

Im using jTable to display CDs info and a child table to show reviews of that CD. I want to be able to only show the edit\delete buttons on the rows for the user that is logged in. I have been trying to follow the suggestions made on: https://github.com/hikalkan/jtable/issues/113
https://github.com/hikalkan/jtable/issues/893
https://github.com/hikalkan/jtable/issues/620
Can honestly say im not having much luck with any of these examples. We had been told to include some jquery in our assignment so I chose to go with using it for my table data. Im wishing now id just done something very basic!
Working jTable without condition:
display: function (reviewData) {
//Create an image that will be used to open child table
var $img = $('<img class="child-opener-image" src="/Content/images/Misc/list_metro.png" title="List Reviews" />');
//Open child table when user clicks the image
$img.click(function () {
$('#ReviewTableContainer').jtable('openChildTable',
$img.closest('tr'),
{
title: "Your reviews on this album",
actions: {
listAction: 'childReviewActions.php?action=list&ID=' + reviewData.record.CDID,
deleteAction: 'childReviewActions.php?action=delete&ID=' + reviewData.record.CDID,
updateAction: 'childReviewActions.php?action=update&ID=' + reviewData.record.CDID
},
fields: {
userID: {
key: true,
create: false,
edit: false,
list: false
},
userName: {
title: 'User',
edit: false,
width: '20%'
},
reviewDate: {
title: 'Review date',
width: '20%',
type: 'date',
edit: false,
displayFormat: 'dd-mm-yy'
},
reviewText: {
title: 'Review',
type: 'textarea',
width: '40%'
}
},
Issue 620 attempt:
actions: {
listAction: 'childReviewActions.php?action=list&ID=' + reviewData.record.CDID,
#if (reviewData.record.userID == <?php echo mysql_real_escape_string($_SESSION['ID']);?>)
{
deleteAction: 'childReviewActions.php?action=delete&ID=' + reviewData.record.CDID,
updateAction: 'childReviewActions.php?action=update&ID=' + reviewData.record.CDID
}
},
This way gives me compile error: invalid property id on the IF statement.
If I take out the # in the if statement I get: missing : after property id.
Issue 113 & 893 attempt:
actions: {
listAction: {
url:'http://localhost/childReviewActions.php?action=list&ID=' + reviewData.record.CDID
//updateAction: {
//url:'childReviewActions.php?action=update&ID=' + reviewData.record.CDID,
//enabled: function (data) {
//return data.record.userID = <?php echo mysql_real_escape_string($_SESSION['ID']);?>;
//}
//}
},
On this I couldnt even get it to list the contents of the child table. It keeps coming back with 404 not found error: The requested url /[object object] was not found on this server. Has anyone any ideas how to get these examples working on have a different example of how to get the table to enable\enable the edit, update buttons? This is all new to me so I apologise now
rowInserted: function (event, data) {
//After child row loads. Check if the review belongs to the member logged in. If not remove the edit/delete buttons
if (data.record.userID != $user) {
data.row.find('.jtable-edit-command-button').hide();
data.row.find('.jtable-delete-command-button').hide();
}
else{
//If a review record does belong to the user set variable to true so the add new review link can be hidden after all records have been loaded
$memberReviewExists = true;
//Also needed here for when a new record is inserted
$(".jtable-add-record").hide();
}
},
recordsLoaded: function (event, data) {
if (typeof $memberReviewExists != 'undefined' && $memberReviewExists == true){
$(".jtable-add-record").hide();
$memberReviewExists = null;
}
else {
//No review currently exists for this user so show the Add review link $(".jtable-add-record").show();
}
},
recordDeleted: function (event, data) {
//User has deleted their review. Re-show the add new review link
$(".jtable-add-record").show();
}
The following worked for me. It hides the edit/delete button on rows where the current user is not the authorized user. Note: I added a column for authorizedUser in the mysql table and use that to know if the user is allowed or not.
rowInserted: function(event, data){
var $currentUser='<?php echo $_SESSION['email']?>';
if (data.record.authorizedUser != $currentUser) {
data.row.find('.jtable-edit-command-button').hide();
data.row.find('.jtable-delete-command-button').hide();
}
},
#Toni Your code contains asp.net code too. # is ASP.NET Directive.

Select2 - avoiding duplicates tags

How can I avoiding duplicates tags in Select2 input?
When I type tag name on the keyboard string is added to input field, but when I select tag from dropdown list (results from the database) the id is added to input (look at console.log on screenshot). So I can select tag from list and add the same tag from keyboard.
Moreover, I need the text of tags, not id from dropdown list while submit a form.
Full resolution
HTML:
<input type="hidden" id="categories" name="categories" style="width:100%" value="${categories}">
JS:
$("#categories").select2({
tags: true,
tokenSeparators: [","],
placeholder: "Dodaj",
multiple: false,
minimumInputLength: 3,
maximumInputLength: 50,
maximumSelectionSize: 20,
ajax: {
quietMillis: 150,
url: '${request.route_url("select2")}',
dataType: 'json',
data: function (term, page) {
return {
q: term,
page_limit: 10,
page: page,
};
},
results: function (data, page) {
var more = (page * 10) < data.total;
return {results: data.categories, more: more};
}
},
initSelection: function (element, callback) {
var data = [];
$(element.val().split(",")).each(function () {
data.push({id: this, text: this});
});
callback(data);
},
createSearchChoice: function (term) {
return { id: term, text: term };
},
}).change(function (e) {
if (e.added) {
console.log($("#categories").val())
console.log(e)
}
});
Have same problem, but I figured it out to find a way around.
I'm getting text and ids, but on the server side I'm creating from given id new objects, which are well read.
$tagsArray = explode(',', $tagNames); // it contains of my input select2 value (with ids)
foreach ($tagsArray as $tag)
{
if (is_numeric($tag))
{
$tags->append(TagQuery::create()->filterById($tag)->findOneOrCreate());
}
elseif (!empty($tag))
{
$tags->append(TagQuery::create()->filterByName($tag)->findOneOrCreate());
}
}
Hope it helps.
at first use select 2
and then do this:
$("select").change(function() { var tr = $(this).closest("tr");
tr.find("select option").attr("disabled",""); //enable everything
//collect the values from selected;
var arr = $.map
(
tr.find("select option:selected"), function(n)
{
return n.value;
}
);
//disable elements
tr.find("select option").filter(function()
{
return $.inArray($(this).val(),arr)>-1; //if value is in the array of selected values
}).attr("disabled","disabled"); });

jQuery ui autocomplete usin JSON file

I am having some trouble getting autocomplete to work specifically with a json file. It
giving following error whenever something is entered in the text box
url is undefined
following is my jQuery code
$(document).ready(function() {
$('#autocomplete').autocomplete({
minChars: 1,
source: function(request, response) {
var url='dataa.json';
$.getJSON(url,{term: request.term},function(data){
response($.map(data.ledgers, function(item) {
return item.value;
}));
})
}
});
});
and the JSON
{
"ledgers":
[
{
"id":"2001",
"name":"Bharat"
},
{
"id":"2003",
"name":"Gaurav"
},
{
"id":"2002",
"name":"Pankaj"
},
{
"id":"2022",
"name":"Purchase"
},
{
"id":"2007",
"name":"Ram"
},
{
"id":"2008",
"name":"Ramesh"
},
{
"id":"2009",
"name":"Suresh"
}
]}
Your JSON file format needs to contain value or label (or both). Change name to value and it should work fine.
$('#autocomplete').autocomplete({
minChars: 1,
source: function(request, response) {
var url='dataa.json';
$.getJSON(url,{term: request.term},function(data){
response($.map(data.ledgers, function (value, key) {
return {
label: value,
value: key
};
}));
})
}
});
Try adding 'use strict'; at the top of your $(document).ready(). That may point out what the problem is...
return item.value;
item does not have a value, try returning id or name, which it does have.

Categories

Resources