jQuery new option needs sorting - php

I've got two dropdowns, as a result of changing the first one it triggers a jquery change() that does a post with the company id from the first dropdown. That then runs a sql query to get a list of people that work for that company and fills the select box with options. This is working fine and I've got the sql query set to ORDER BY admin_name. But when jquery starts inserting the options into the dropdown it appears to be sorting by the option value instead (admin_id). What can I do to keep the options ordered by the admin_name (the text of the option). Below is the jQuery code responsible for adding the options:
$.post("listSignedBy.php", { company_id: company_id },
function(data) {
alert(data); <-- this shows that the data is sorted correctly by the admin name.
var select = $('#signed_by');
if(select.prop) {
var options = select.prop('options');
}
else {
var options = select.attr('options');
}
$('option', select).remove();
var obj = jQuery.parseJSON(data);
options[options.length] = new Option('-- Select Signed By --', '');
$.each(obj, function(val, text) {
options[options.length] = new Option(text, val);
});
select.val(selectedOption);
});
Thank you for any assistance and please let me know if you need any further information to help troubleshoot/fix.
As requested, example JSON data:
{"19082":"Aaron Smith","19081":"Becky Doe"}
So in this case what I WANT is:
<option value='19082'>Aaron Smith</option>
<option value='19081'>Becky Doe</option>
But instead of sorting by the text, it's sorting by the value so I get:
<option value='19081'>Becky Doe</option>
<option value='19082'>Aaron Smith</option>

The object is not sorted.. It is actually getting inserted in the order how it is iterated.
However, in case if the order of returned response is not in the desired order then the best way is it insert the options first and sort the options. See below,
DEMO: http://jsfiddle.net/gGd82/3/
// convert OPTIONs NodeList to an Array
// - keep in mind that we're using the original OPTION objects
var ary = (function(nl) {
var a = [];
for (var i = 0, len = nl.length; i < len; i++) {
a.push(nl.item(i));
}
return a;
})(options);
// sort OPTIONs Array
ary.sort(function(a, b) {
return a.text < b.text ? -1 : a.text > b.text ? 1 : 0;
});
// remove all OPTIONs from SELECT (don't worry, the original
// OPTION objects are still referenced in "ary") ;-)
options.length = 0;
// (re)add re-ordered OPTIONs to SELECT
select.html(ary);
select.prepend($('<option />').text('-- Select Signed By --').val(''));
References: Sorting dropdown list using Javascript

I was able to get it working by creating the following function and then referencing that function just after the .each() that entered all of the options in:
function Sort(a, b) {
return (a.innerHTML > b.innerHTML) ? 1 : -1;
};
$.post("listSignedBy.php", { company_id: company_id },
function(data) {
var select = $('#signed_by');
if(select.prop) {
var options = select.prop('options');
}
else {
var options = select.attr('options');
}
$('option', select).remove();
var obj = jQuery.parseJSON(data);
options[options.length] = new Option('-- Select Signed By --', '');
$.each(obj, function(val, text) {
options[options.length] = new Option(text, val);
});
$('#signed_by option').sort(Sort).appendTo('#signed_by');
select.val(selectedOption);
});

Related

Live filter in Laravel

I have a form that looks like below.
I have three "white" dropdowns to filter the value for the Equipment Registration Tag dropdown ( The values of the dropdown input field that has the Equipment Registration Tag label will only come out after the user selects values for the three "white" dropdowns). So the Equipment Registration Tag values will differ based on the "white" dropdowns value.
I want it to be a live filter, the dropdown options will change immediately every time user selects the "white" dropdown value. Currently, my approach is to use the onchange=" this.form.submit()" attribute on the "white" dropdowns and return the values after the filter, but I realize this method has a disadvantage which is a user might accidentally submit the form when changing the value of "white" dropdowns. How can I prevent this and only allow users to submit the form by clicking the save button?
$this->Calibration_Location = $request->get('selected_location');
$this->Calibration_Category = $request->get('selected_category');
$this->categories = Equipment::select('Category')->distinct()->get()->toArray();
$this->locations = Equipment::select('Location')->distinct()->get()->toArray();
$matchThese = ['Category' => $this->Calibration_Category, 'Location' => $this->Calibration_Location];
$this->Registration_Select_Tags = Equipment::select('Registration Tag')->distinct()->where($matchThese)->get();
I have also tried jQuery, but I can only trigger by a specified dropdown field, not any one of them.
<script type="text/javascript">
$(document).ready(function() {
var location, category
$('#selected_transfer_location').change(function() {
location = $(this).val();
console.log(location);
$('#selected_transfer_category').change(function() {
category = $(this).val();
console.log(category);
});
// $('#transfer_registration_tag').find('option').not(':first').remove();
$.ajax({
url: 'Transaction/' + location + '/' + category,
type: 'get',
dataType: 'json',
success: function(response) {
var len = 0;
if (response.data != null) {
len = response.data.length;
}
if (len > 0) {
for (var i = 0; i < len; i++) {
var id = response.data[i]['Registration Tag'];
var name = response.data[i]['Registration Tag'];
var option = "<option value='" + id + "'>" + name +
"</option>";
$("#transfer_registration_tag").append(option);
}
}
}
})
});
});
</script>
I hope my question is clear, still new to Laravel and I hope could receive some hints from you.
First approach could be that, you use call ajax Query on change of each on of them and fetch filtered results. Something like this:
$('#dropdown1, #dropdown2, #dropdown3').change(function(){
var val1 = $('#dropdown1').val();
var val2 = $('#dropdown2').val();
var val3 = $('#dropdown3').val();
//And then your ajax call here to fetch filtered results.
});
Only issue is this Ajax call will occur min 3 times, one for each of them.
Second approach could be you give small button below those dropdowns, something like FetchTags. When user selects all the 3 values, will click on that button and you call your ajax onClick of that btn. So that your Ajax will be called only once.
You can use livewire to do that. It easy.
To install it, you have to use composer by taping the fowllowing command:
composer req livewire/livewire
Please check this tutorial to see how to how to do what you want to do using the framework.

Fixing jQuery plugin to handle duplicating nested fields with unique ID's

I have a quick question for you guys here. I was handed a set of lead generation pages and asked to get them up and running. The forms are great, expect for one small issue... they use the jQuery below to allow users to submit multiple instances of a data set by clicking an "Add another item" button. The problem is that the duplicated items are duplicated EXACTLY. Same name, id, etc. Obviously, this doesn't work when attempting to process the data via PHP, as only the first set is used.
I'm still learning jQuery, so I was hoping that someone could point me in the right direction for how to modify the plugin below to assign each duplicated field an incremental integer on the end of the ID and name assigned. So, the fields in each dataset are Role, Description, Age. Each additional dataset will use the ID & name syntax of fieldname#, where # represents numbers increasing by 1.
Thanks in advance for any advice!
/** https://github.com/ReallyGood/jQuery.duplicate */
$.duplicate = function(){
var body = $('body');
body.off('duplicate');
var templates = {};
var settings = {};
var init = function(){
$('[data-duplicate]').each(function(){
var name = $(this).data('duplicate');
var template = $('<div>').html( $(this).clone(true) ).html();
var options = {};
var min = +$(this).data('duplicate-min');
options.minimum = isNaN(min) ? 1 : min;
options.maximum = +$(this).data('duplicate-max') || Infinity;
options.parent = $(this).parent();
settings[name] = options;
templates[name] = template;
});
body.on('click.duplicate', '[data-duplicate-add]', add);
body.on('click.duplicate', '[data-duplicate-remove]', remove);
};
function add(){
var targetName = $(this).data('duplicate-add');
var selector = $('[data-duplicate=' + targetName + ']');
var target = $(selector).last();
if(!target.length) target = $(settings[targetName].parent);
var newElement = $(templates[targetName]).clone(true);
if($(selector).length >= settings[targetName].maximum) {
$(this).trigger('duplicate.error');
return;
}
target.after(newElement);
$(this).trigger('duplicate.add');
}
function remove(){
var targetName = $(this).data('duplicate-remove');
var selector = '[data-duplicate=' + targetName + ']';
var target = $(this).closest(selector);
if(!target.length) target = $(this).siblings(selector).eq(0);
if(!target.length) target = $(selector).last();
if($(selector).length <= settings[targetName].minimum) {
$(this).trigger('duplicate.error');
return;
}
target.remove();
$(this).trigger('duplicate.remove');
}
$(init);
};
$.duplicate();
Add [] to the end of the NAME attribute of the input field so for example:
<input type ="text" name="name[]"
This way your $POST['name'] will hold an array of strings. For that element. It will be an array with keys that are numbers from 0 to however many items it holds.

jQuery Looping JSON Data

I have created APIs to retrieve data from my server and then I get the data with json format like this :
{
"items": [
{
"2013-03-28": 1771,
"2013-03-29": 1585,
"2013-03-30": 1582,
"2013-03-31": 1476,
"2013-04-01": 2070,
"2013-04-02": 2058,
"2013-04-03": 1981,
"2013-04-04": 1857,
"2013-04-05": 1806,
"2013-04-06": 1677,
"2013-04-07": 1654,
"2013-04-08": 2192,
"2013-04-09": 2028,
"2013-04-10": 1974,
"2013-04-11": 1954,
"2013-04-12": 1813,
"2013-04-13": 1503,
"2013-04-14": 1454,
"2013-04-15": 1957,
"2013-04-16": 1395
}
]
}
How do I looping with my json data dynamically using jQuery?
My code :
<html>
<head></head>
<body>
<script src="jquery-1.9.1.js"></script>
<script>
$(document).ready(function() {
$.ajax({
type : "GET",
url: "myurl.php",
cache: false,
dataType: "jsonp",
success:function(data){
if(data==''){
alert('Fail');
}else{
alert('Success');
}
}
})
});
</script>
</body>
</html>
How do I modify my jQuery to get data dynamically following the date that the data will change every day as in the example I wrote above data??
Thanks before...
There are a few things to consider with your example data, but in your case, the following will do the trick:
var importantObject = data.items[0];
for(var item in importantObject ){
var theDate = item;//the KEY
var theNumber = importantObject[item];//the VALUE
}
Here is a working example
But what does all this mean?...
First of all, we need to get the object that we want to work with, this is the list of dates/numbers found between a { } (which means an object) - an array is defined as [ ]. With the example given, this is achieved like so:
var importantObject = data.items[0];
because items is an array, and the object we want is the first item in that array.
Then we can use the foreach technique, which effectively iterates all properties of an object. In this example, the properties are the date values:
for(var item in importantObject ){ ... }
Because we are iterating the properties, item will be the property value (i.e. the date bit), so item is the date value:
var theDate = item;//the KEY
Finally we get the number part. We can access the value of any given object property by using the string value of the property index (relative to the object), like so:
var theNumber = importantObject[item];//the VALUE
If you already know which date you want the value for, then you can access it directly like so:
var myValue = data.items[0]["2013-04-16"];//myValue will be 1395 in this example
Using jQuery.each() loop through the items
$.each(data.items[0], function (key, value) {
console.log(key + ": " + value);
var date = key;
var number = value;
});
DEMO HERE
You can use the jQuery each function to do this. For example like this:
$.each(data, function(k, v) {
// Access items here
});
Where k is the key and v is the value of the item currently processed.
//get your detail info.
var detail = data.items[0];
$.each(detail, function(key, val) {
console.log(key + ": " + val);
}

Remove drop down entries based on previous selection

I've looked through stackoverflow for an answer and am almost there but need some help.
I have multiple drop down lists with the same options in them. For example three identical lists with the following:
<label for='distlist_1'>Distribution List 1</label>
<select name='distlist_1'>
<option value=''>Please Select:</option>
<option value='1'>All</option>
<option value='2'>All Managers</option>
<option value='3'>Leavers</option>
</select>
The only difference being the name eg, distlist_1, 2, 3 etc. I can add ids if necessary.
When a user selects an option in the first drop down list I need it to be removed from all other drops downs. I found a script that did this.
$('option').click(function(){
$('option:contains(' + $(this).html() +')').not(this).remove();
});
But I need it so that if the user then decides, 'wait I don't need that option in drop down list 1 after all', she picks something else and the option reappears in the other drop downs. The code above removes the options then there is no way of retrieving them until if you click enough they all disappear.
This actually does what you want... This is based on jquery 1.7 and the on() event binder
$(document).ready(function (){
$('select').on('focus', function() {
// on focus save the current selected element so you
// can place it back with all the other dropdowns
var current_value = $(this).val();
// bind the change event, with removes and adds elements
// to the dropdown lists
$(this).one('change.tmp', { v : current_value }, function(e)
{
if ($(this).val() != '')
{ // do not remove the Please select options
$('option[value="' + $(this).val() + '"]')
.not($('option[value="' + $(this).val() + '"]', $(this)))
.remove();
}
if (e.data.v != '')
{ // do not add the Please select options
$('select').not($(this)).append($('option[value="' + e.data.v + '"]', $(this)).clone());
}
});
// on blur remove all the eventhandlers again, this is needed
// else you don't know what the previously selected item was.
$(this).on('blur.tmp', { v : current_value}, function (e)
{
$(this).off('blur.tmp');
$(this).off('change.tmp');
});
});
});
The only thing it doesn't do is ordering everything in the right order. You will have to think of your own way of doing that at the .append function.
I ended up using this as it was concise...
jQuery(document).ready(function() {
var selects = $('.mapping')
selects.change(function() {
var vals = {};
selects.each(function() {
vals[this.value] = true;
}).get();
selects.not(this).children().not(':selected').not(':first-child').each(function() {
this.disabled = vals[this.value];
});
});
});

Populate Select list Menu though Ajax Jquery

Before anybody says this is a duplicate of this and that question, let me assure you I have tried the solutions there and I have failed. I am using a solution offered in this website to come up with my solution and I believe I am 90% done except for one error. I want to display a list of all codes that have a certain common ID associated with them.
Here is my PHP code that I am using to get a list of codes
<?php
$budgetcode=$_POST['budgetcode'];
//$budgetcode=2102;
$selectcodes="SELECT * FROM tblbudget_codes WHERE T1 = $budgetcode";
$query=$connection->query($selectcodes);
$count=$query->num_rows;
if($count < 1)
{
die('0');
}
else{
while($row=$query->fetch_array()){
$T1=($row['T1']);
$T2=($row['T2']);
$T3=($row['T3']);
$T4=($row['T4']);
$optionValue = $T1."-".$T2."-".$T3."-".$T4;
echo json_encode("<option>$optionValue</option");
// echo json_encode('1');
}
}
?>
Here is the ajax call i am using to fetch the codes
$.post("Functions/getbudgetcodes.php",{budgetcode:budgetid},function(data){
if(data!='0')
{
$("#budgetcode").html(data).show();
$("#result").html('');
}
else{
$("#result").html('<em>No codes found. Contact Administrator</em>');
}
},'json')
//alert(budgetid);
})
The problem here is that jquery does not understand the data it is receiving if it is not numeric. E.g if I comment out the json_encode('1') and put random html code instead of data in my success part, I get results displayed in my browser. Can anybody tell me why jquery is only recognizing numeric values that are being echoed from PHP and not varchar values. Using jquery 1.4.2. Any help appreciated.
EDIT
I have managed upto some point and now i am stuck. I have used John's Answer and here is my jquery code. i just need to split the array and append each element to a variable one at a time like here
here is the code. Somebody please tell how I split (data). i can alert it but it is comma seperated. Just need to get the individual items append them to variable html and then display it.
$.post("Functions/getbudgetcodes.php",{budgetcode:budgetid},function(data){
if(!$.isEmptyObject(data))
{
//alert (data);
// alert(split (data))
var html = '';
var len = data.length;
for (var i = 0; i< len; i++) {
html += '<option>' +data+ '</option>';
}
$("#budgetcode").html(html).show();
$("#result").html('');
}
else{
$("#result").html('<em>No codes found. Contact Administrator</em>');
}
},'json')
I would skip JSON altogether:
PHP
echo "<option>$optionValue</option>";
Everything else should work.
Finally figured it out. Here is the php code
$selectcodes="SELECT * FROM tblbudget_codes WHERE T1 = $budgetcode";
$query=$connection->query($selectcodes);
$count=$query->num_rows;
if($count < 1)
{
die('0');
}
else{
while($row=$query->fetch_array()){
$data[] = $row;
}
echo json_encode($data);
}
?>
Here is the jquery code
$.post("Functions/getbudgetcodes.php",{budgetcode:budgetid},function(data){
if(!$.isEmptyObject(data))
{
//alert (data);
var html = '';
var joiner='';
var len = data.length;
for (var i = 0; i< len; i++) {
joiner=([data[i].T1,data[i].T2,data[i].T3, data[i].T4].join('-'));
//alert(joiner);
html += '<option>'+joiner+'</option>';
}
$("#budgetcode").html(html).show();
$("#result").html('');
}
else{
$("#result").html('<em>No codes found. Contact Administrator</em>');
}
},'json')
Had to use join to join the multiple codes using a dash. Hope this helps. The PHP part and part of the jquery was inspired by this question
FWIW, for populating select lists I usually use the following jQuery code:
// populates select list from array of items given as objects: {
name: 'text', value: 'value' }
function populateSelectList(parent, items) {
parent.options.length = 0;
if (parent.options.length === 0) {
parent.options[0] = new Option("Please select something...", "");
}
$.each(items, function (i) {
if (typeof (this) == 'undefined') { return; }
parent.options[el.options.length] = new Option(this.name, this.value);
});
}
and to call the above function i pass the results of an ajax call using the map method where #select is the selector for the parent select element. I am setting the Text property to the name and Value to the value but that should change according to the objects returned by the ajax call (e.g. assuming the returned objects have a Value and Text properties).
populateSelectList($('#select').get(0), $.map(results, function
(result) { return { name: result.Text, value: result.Value} }));

Categories