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

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.

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.

Conflicting jquery functions

I have built two functions which work separately (when the other is deleted) but do not work together. The overall aim is that when a person selects the number of results they want to see per page, this then reloads the page, and the value is put in the url and then retrieved using get in php; and then on the new page the selected value in the drop down menu to is the value what triggered the reload.
Jquery
$(document).ready(function(){
//the first section takes the value from the php script and then selects the option if it's not null - this works fine on it's own
var data = "<?php echo $rp;?>";
if (data){
$("#bo2 option[value="+data+"]").attr('selected', 'selected');
}
//this too works fine on it's own but not with the above
$('#bo2').change(function(){
var opt = $(this).val();
var url = "sales.php?results=";
var newurl = url + opt;
window.location.replace(newurl);
});
});
Together, the first works fine, in that it re-selects the right value if, say, I put ?results=50 after sales.php but then the jQuery to trigger the reload doesn't work. What am I doing wrong?
Just to clarify. The first page is called "sales.php" and the drop down menu has the currently selected value of "10", with 25 and 50 being other options. When I click on another number the jquery doesn't work. However should I type into the url the ending "?result=50", for example, it does work; and the drop down menu now shows 50; when i click on ten, the url updates, and the drop down shows ten also; the problem then is they seem to conflict only at the start, as it were.
It would seem the problem may concern how jquery deals with php. Take for example the following first example which works, and then the second which doesn't:
1)
$(document).ready(function(){
$('#bo2').change(function(){
var opt = $(this).val();
var url = "sales.php?results=";
var newurl = url + opt;
window.location.replace(newurl);
});
});
2) This change function however will not trigger a reload of the page because of the inclusion of the php defined jquery variable.
$(document).ready(function(){
var data = "<?php echo $rp;?>";
$('#bo2').change(function(){
var opt = $(this).val();
var url = "sales.php?results=";
var newurl = url + opt;
window.location.replace(newurl);
});
});
This achieves what I want (I don't know if the php posed a problem or not). The function is from here - Get url parameter jquery Or How to Get Query String Values In js.
Also, I'm surprised nobody more experienced than me didn't point out what also seems to have made a difference; the "first" function in the original post needs to in fact be second.
So the below will reload a new page, when a user clicks on an option in a select menu with pre-defined options for how many results they want to see per page; this value will then show in the url, and, importantly, the current select value of the select menu will now be this value also; this is important so that if the user goes back to the original number of views, the change() function works still.
$(document).ready(function(){
var getUrlParameter = function getUrlParameter(sParam) {
var sPageURL = decodeURIComponent(window.location.search.substring(1)),
sURLVariables = sPageURL.split('&'),
sParameterName,
i;
for (i = 0; i < sURLVariables.length; i++) {
sParameterName = sURLVariables[i].split('=');
if (sParameterName[0] === sParam) {
return sParameterName[1] === undefined ? true : sParameterName[1];
}
}
};
var data = getUrlParameter('results');
$('#bo2').change(function(){
var opt = $(this).val();
var url = "sales.php?results=";
var newurl = url + opt;
window.location.replace(newurl);
});
if (data)
{
$("#bo2 option[value="+data+"]").attr('selected', 'selected');
}
});

jQuery - Search Mysql for results, then display within table, but also have a click link for each record

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
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.
<script type="text/javascript">
$(document).ready(function() {
$(".click").click(function() {
var name = $("#name").val();
var name = $(this).attr("id");
$('#2').load("mysqlrequest_unique.php?recordid=" +name);
});
$("#get").click(function() {
var sales_record_number = "sales_record_number=" + $("#sales_record_number").val() + "&";
var item_id = "item_id=" + $("#item_id").val() + "&";
var user_id = "user_id=" + $("#user_id").val() + "&";
var buyer_fullname = "buyer_fullname=" + $("#buyer_fullname").val() + "&";
var sale_date = "sale_date=" + $("#sale_date").val() + "&";
var paypal_transaction_id = "paypal_transaction_id=" + $("#paypal_transaction_id").val() + "&";
var ship_to_zip = "ship_to_zip=" + $("#ship_to_zip").val() + "&";
var item_title = "item_title=" + $("#item_title").val() + "&";
$('#1').load("mysqlrequest_all.php?"+sales_record_number+item_id+user_id+buyer_fullname+sale_date+paypal_transaction_id+ship_to_zip+item_title, function(){
var name = $("#name").val();
var name = $(this).attr("id");
$('#2').load("mysqlrequest_unique.php?recordid=" +name);
}
);
});
});
</script>
<div id="1" name='container_display_all'></div>
<div id="2" name='container_display_unique'></div>
This is what each row would have in the table, which doesnt work when its contained in generated html using a jQuery
<a class = 'click' id = '19496'>19496</a>
This isn't working because you are adding html elements dynamically and the event handlers aren't being added to the dynamically added elements.
$(document).ready(...) is only run when the document loads. So if all the elements that have the class click are being added dynamically, this bit of code $(".click") (inside $(document).ready(...) ) will return a jquery object that contains no elements (as there are currently none in the DOM with the class click).
Then later your elements (with class click) are added to the DOM but have no handlers on them. What you need to do is set the handlers for those object when you add them.
So change this line:
$('#1').load("mysqlrequest_all.php?"+sales_record_number+item_id+user_id+buyer_fullname+sale_date+paypal_transaction_id+ship_to_zip+item_title);
to this:
$('#1').load("mysqlrequest_all.php?"+sales_record_number+item_id+user_id+buyer_fullname+sale_date+paypal_transaction_id+ship_to_zip+item_title, function(){
$(".click").click(function() {
var name = $("#name").val();
var name = $(this).attr("id");
$('#2').load("mysqlrequest_unique.php?recordid=" +name);
});
}
);
This code will execute the function that is passed once the new html is loaded into the first div, which will add the needed handlers to the new elements.

Dynamically Created Checkbox calculation, Not showing properly

I have a javascript function that create Checkbox by drop_down's selection. When I clicked the add button , system will create checkbox(es) with values.
function addElement()
{
var e= document.getElementById('top-addon');
var tops = e.options[e.selectedIndex].text;
var tops_value=e.options[e.selectedIndex].value;
// alert(tops_value);
var ni = document.getElementById('myDiv');
num += 1;
//var newdiv = document.createElement('div');
var countedName = num;
// newdiv.setAttribute('id',Name);
var x = document.createElement("input");
x.type = "checkbox";
x.name = "toppings[]";
x.setAttribute('id',countedName);
x.checked = true;
x.value = tops_value;
//var inner_text = tops + '<a href=\'#\' onclick=\'removeElement('+countedName+')\'> [x] </a>';
//var text= document.createTextNode(inner_text);
x.innerHTML=tops;
ni.appendChild(x);
//ni.appendChild(inner_text);
}
I had make some screenshots to explain you my current problems. Please check my screenshot for more clear picture.
This is like this, for an item like ice-cream, customers can add many toppings example , nuts, jelly etc.
Then I have another problem.Created checkbox's are not shown . I can only see square box(es)
Please see my second attached picture below.Seems okay to me.But I can't see any description text(s).
What I am trying to achieve is
to show selection
Calculate the items,they will be generated with checked value. I have already achieve the code to remove the generated toppings. So I want to calculate the total value of generated items and they should be changeable.
Example. if remove a generated item. Total toppings should decrease.Thanks for your help in advance.
For your first problem: In order to display text for a checkbox, you should put checkbox inside label. Here is modified code for you
function addElement()
{
var e= document.getElementById('top-addon');
var tops = e.options[e.selectedIndex].text;
var tops_value=e.options[e.selectedIndex].value;
// alert(tops_value);
var ni = document.getElementById('myDiv');
num += 1;
//var newdiv = document.createElement('div');
var countedName = num;
// newdiv.setAttribute('id',Name);
var x = document.createElement("input");
x.type = "checkbox";
x.name = "toppings[]";
x.setAttribute('id',countedName);
x.checked = true;
x.value = tops_value;
//x.innerHTML=tops; We don't need to set text to checkbox.
/* These lines are added */
var label = document.createElement("label");
label.appendChild(x);
var span = document.createElement("span");
span.innerText = tops;
label.appendChild(span);
/* End of added lines */
// Beware that we are adding label to div, instead of checkbox.
ni.appendChild(label);
}
For your second problem: To calculate grand total of cart, you need to define a function (let's say calculateTotal) that implements sort of this pseudocode:
function calculateTotal
begin
get all checkboxes under myDiv
for each selected check box
begin
get check box id
get substring of id, after comma (",")
add substring (price) to total
end
end
This method should be triggered whenever user clicks add item button, remove item button, and checkboxs' onChange events fire.
I guess this answer should address your issue with checkboxes text: https://stackoverflow.com/a/10143276/1492792

Total value with JavaScript and PHP

I'm using this form script to automatically calculate totals. Now I need to get that total and add it to a database via PHP and MySQL.
I don't know how to 'name' the totalPrice div, so that I can pass its value to the database.
Edit:
I'm still not getting results in the database. I'm now using $_POST[totalValue] for the field set and totalPrice for the field name.
HTML:
<div id="totalPrice"></div></div>
<input type="hidden" name="totalValue" id="totalValue" />
JavaScript:
$("#vendorform").submit(function(){
var totalValue = document.getElementById('totalValue');
totalValue.value = vendorPrice; //the actual total value
});
function calculateTotal()
{
//Here we get the total price by calling our function
//Each function returns a number so by calling them we add the values they return together
var vendorPrice = getTentPrice() + getElecPrice() + getPropanePrice();
//display the result
var divobj = document.getElementById('totalPrice');
divobj.style.display='block';
divobj.innerHTML = "Total Price Vendor $"+vendorPrice;
}
The vendorPrice variable is not available outside the scope of the function calculateTotal. You could make vendorPrice a global variable, but that's a bit of an ugly hack.
Alternatively, you could do something like this:
function calculateTotal()
{
var vendorPrice = getTentPrice() + getElecPrice() + getPropanePrice();
var divobj = document.getElementById('totalPrice');
divobj.style.display='block';
divobj.innerHTML = "Total Price Vendor $"+vendorPrice;
return vendorPrice; // <-- ADDED
}
And this:
$("#vendorform").submit(function(){
var totalValue = document.getElementById('totalValue');
totalValue.value = calculateTotal(); // <-- CHANGED
});
This way, you assign the value that is now returned by calculateTotal() to totalValue.value.
By the way: since it looks like you're already using jQuery, you can rewrite your code like this:
// [...]
var divobj = $('#totalPrice');
divobj.css('display', 'block');
divobj.text("Total Price Vendor $"+vendorPrice);
// [...]
var totalValue = $('#totalValue');
totalValue.val(calculateTotal());
This makes it a bit more readable (although that's debatable) and a bit more cross-browser reliant. jQuery has great docs (e.g. the documentation on .val()). If you're going to use jQuery more often I can highly recommend bookmarking the docs and skimming through them.
Using jQuery:
$("#cakeform").submit(function(){
var price = $("#totalPrice").text().replace(/[\s\S]+\$/,"")
$("#cakeForm").append('<input type="hidden" name="estimated_price" value="' + price + '" />')
})
But as #nick-rulez pointed out, is usually not a good idea to save calculated values in a database.
You can set the value to:
<input type="hidden" name="totalValue" id="totalValue" />
Which you have to put inside your <form>...</form>.
When you submit the form you're going to receive input's value.
You can set the value to the hidden field with this sniped:
JS
var totalValue = document.getElementById('totalValue');
totalValue.value = myValue; //myValue is the total
JavaScript:
function calculateTotal()
{
var Price = getTshirtPrice() + getTshirtType() + getTshirtColour() +
getTextColour();
var divobj = document.getElementById('textbox');
divobj.value = "Total Price For the T-shirt: £"+Price;
return Price;
}
HTML:
<div id="totalPrice"><input type="text" id="textbox"></div>
Do that. It works perfectly fine.

Categories