reading a drag and drop ordered list via JavaScript - javascript

I have an application (drag and drop using JqueryUI.GridSort) that allows the user to upload photos, and then sort the photos in the order that they would like using drag and drop.
On page load, the user is prompted to upload photos which are posted to the next page. When they arrive on the next page my php script creates a <ul id="sortable"> containing <li> for each of the files they uploaded. For each picture that they have uploaded to the site, a new <li> is created. Inside of that <li> is a <img> that sets the picture for <li> with the image they have uploaded.
My goal is to be able to "save" the order of the pictures after they have arranged them in the drag and drop interface. For example, once they have finished arranging and sorting the pictures in the order they want them in, I would like to be able to send them another page that creates an xml file ( I don't need help with the XML, only saving the order) with using the list that they created in the correct order.
After hours of tinkering with PHP, I have come to realization that because PHP is a serverside language, it cannot see what is sorted post render. So my question is, is there a way to have JavaScript or Ajax read the current order of the list, and post it to the next page? If you do know how, could you please provide an example of both the POST from one page, and the post receiving on the other? I am not very familiar with Ajax.
Thank you greatly for any assistance you could provide.
Sample Code (The contents of the foreach statement that creates a LI for each file uploaded)
$imgID++;
echo '<li class="ui-state-default"><img id="'.$imgID.'"'.' src="user_files/'.$file_name.'" draggable="true" height="90" width="95"></li>';
EDIT
main page :
<script>
$('#my_form').on('submit', function() {
var ordered_list = [];
$("#sortable li img").each(function() {
ordered_list.push($(this).attr('id'));
});
$("#ordered_list_data").val(JSON.stringify(ordered_list));
});
</script>
<div id="tesT">
<form id="my_form" action="update_data.php">
<!-- other fields -->
<input type="hidden" id="ordered_list_data"></input>
<input type="submit" value="Proceed to Step 2"></input>
</form>
</div>
update_data.php:
<?php
// process other fields as normal
if(isset($_POST['ordered_list_data'])) {
$img_ordering = json_decode($_POST['ordered_list_data']);
echo "1";
} else {
echo "nodata";
}
// do things with the data
?>

I built a JSFiddle doing basically the same thing that David posted.
I added a piece to write out the result to a div on the page, so you can see what's going on:
<input type="button" id="savebutton" value="save"/>
<div id="output"></div>
<form id="listsaveform" method="POST" action="script.php">
<input type="hidden" name="list" id="hiddenListInput" />
</form>
Javascript:
$(function() {
$( "#sortable" ).sortable();
$( "#sortable" ).disableSelection();
$( "#savebutton" ).click(function() { LISTOBJ.saveList(); });
});
var LISTOBJ = {
saveList: function() {
var listCSV = "";
$( "#sortable li" ).each(function() {
if (listCSV === "") {
listCSV = $(this).text();
} else {
listCSV += "," + $(this).text();
}
});
$("#output").text(listCSV);
$("#hiddenListInput").val(listCSV);
//$("#listsaveform").submit();
}
}

If you're using a <form> you can do something like this (assuming jQuery is being used):
$('#my_form').on('submit', function() {
var ordered_list = [];
$("#sortable li img").each(function() {
ordered_list.push($(this).attr('id'));
});
$("#ordered_list_data").val(JSON.stringify(ordered_list));
});
In essence, what you're doing is looping over the <ul>, fetching each <img> and appending the ids (in order of appearance) to an array. Arrays preserve ordering in JavaScript and JSON, so one can turn it into a JSON string using the JSON.stringify function, set it as the value of a <input type="hidden"> field and then submit the form.
If you want to use AJAX, the functionality is very similar. However, instead of using an onsubmit (or onclick) you'd use $.post.
Let's go with the <form> option since it's simpler. All told you'll have something similar to the above JS along with HTML like this:
<form id="my_form" method="post" action="./update_data.php">
<!-- other fields -->
<input type="hidden" name="ordered_list_data" id="ordered_list_data"></input>
<input type="submit" value="Submit"></input>
</form>
Then, in update_data.php (or whatever your script is named):
<?php
// process other fields as normal
if(isset($_POST['ordered_list_data'])) {
$img_ordering = json_decode($_POST['ordered_list_data']);
} else {
// handle case where there is no data
}
// do things with the data
?>

Related

How to submit form when any value selected from populated textbox using javascript or jQuery without clicking submit button

search.php
In this form, when we type something in textbox, matching words are fetched from api_search.php page and displayed as seen in attached screenshot.
<form role="form" id="frm_search" name="frm_search" method="POST" action="./api_search_p.php" enctype="multipart/form-data" >
<script type="text/javascript">
$(function()
{
$( "#txt_itemname" ).autocomplete({
source: '../user/api_search.php'
});
});
</script>
<input type="text" id="txt_itemname" name="txt_itemname" class="form-control" required data-validation-required-message="Please enter something here">
<button type="submit" class="btn btn-warning"><i class='fas fa-search'></i> </button></span>
</form>
api_search.php
Textbox on search.php is populated from API result data from this page.
-- API data are coming using curl in $result array --
$json = json_decode($result, true);
$arr_searchTerm = array();
if (is_array($json) && !empty($json))
{
foreach ($json as $key1 => $level1)
{
if (is_array($level1) && !empty($level1))
{
foreach ($level1 as $key2 => $level2)
{
array_push($arr_searchTerm, $level2['TITLE']);
}
}
}
}
echo json_encode($arr_searchTerm);
Currently need to click submit button to submit the form. But I want to do so when any word from fetched result is selected / clicked then form should be submitted immediately without clicking submit button.
I tried onselect="this.form.submit()" & onchange="this.form.submit()" with textbox but form is not submitted on any of javascript events.
Please let me know how can I make this working as expected.
Screenshot
You can use select function in your code
$( "#txt_itemname" ).autocomplete({
source: '../user/api_search.php',
select: function(e, ui){
this.value = ui.item.value;
this.form.submit();
}
});
You can try this way. in this case, you can make your API call every time someone inserts something. This means every single letter will make a call
document.querySelector("#txt_itemname").addEventListener('input',(e)=>{
...
})
and additionally, if you do it as an API try to look at this too http_responses with PHP

Unable to Clone HTML & Values into jQuery Datatables 1.10

This question has been asked on a few occasions, for example:
Store Cloned Element in Variable
Copy DOM Element
However, I'm having issues selecting say <div id="XYZ"></div> and cloning it to a variable for the jQuery DataTable fnStateSaveParams to save. When the page refreshes it is then meant to reload the cloned object back into the HTML via fnStateLoadParams. I am trying to use .clone() over .html() because I also need the values stored within the dynamically generated textboxes.
If I'm not saving and loading via the Datatables plugin, then it works perfectly. As soon as I try calling code similar to the below then it ceases to work (please bare in mind I've tried a number of variations to the below code). Has anyone got any ideas or suggestions?
"fnStateSaveParams": function (oSettings, oData) {
var clonedHtml= $("#XYZ").clone(true);
oData.storedHtml = clonedHtml;
},
"fnStateLoadParams": function (oSettings, oData) {
//$("#displayHtml").append(oData.storedHtml);
//$("#displayHtml").html(oData.storedHtml);
//$(oData.storedHtml).prependTo("#displayHtml")
}
<div id="XYZ">
<div data-template="">
<label class="bolder"></label>
<div class="input-append">
<div class="inline-block advancedSearchItem">
<input type="text" id="test1" value="Test Scenario" />
</div>
<a href="#" data-id="" class="btn btn-small btn-danger removeField">
<div class="hidden-phone">Remove</div>
<i class="icon-trash icon-only hidden-tablet hidden-desktop"></i>
</a>
</div>
</div>
</div>
The end scenario will be more complex, however the above is the simplest form of what I am trying to create. If you need more information, feel free to ask and I'll update the question accordingly.
I didn't find a way of utilising .clone() to grab all HTML and Text Box values. However, I did come up with a solution and the code below is for anyone who needs a reference point.
Using .html() (as most will know) will only copy the available HTML and ignore what is essentially 'placeholder' text within text fields. My solution though is to force the value into the HTML rather than being treated as 'placeholder' text, this allows it to be used again when the page is loaded.
$(document).on("click", "#advancedSearchButton", function(event) {
event.preventDefault();
// DO SOME STUFF HERE
$("[data-value]").each(function(index) {
if (index > 0) {
fieldCount++;
$(this).attr("value", $(this).val());
}
});
oTable.fnFilter("");
});
function loadData() {
// ... ... ...
"fnStateSaveParams": function(oSettings, oData) {
oData.advancedSearchHtml = $("#addedSearchFields").html();
oData.fieldCount = fieldCount;
oData.isAdvancedSearch = isAdvancedSearch;
},
"fnStateLoadParams": function(oSettings, oData) {
$("#addedSearchFields").html(oData.advancedSearchHtml);
if (oData.isAdvancedSearch == true) {
$("#collapseElement").removeClass("collapsed");
$("#collapseIcon").removeClass().addClass("icon-chevron-up");
$("#filter").hide();
}
isAdvancedSearch = oData.isAdvancedSearch;
advancedSearchFields = oData.fieldCount;
}
// ... ... ...
}

jQuery: How to submit an array in a form

I have the following form. Each time the users clicks add_accommodation I want to add to an array that I will return to the end point (http://server/end/point).
<form action="http://localhost:3000/a/b/c" method="post">
<div>
<input type="hidden" id="Accommodation" name="accommodation"><div>
</div>
</form>
<div id="accommodation_component">
<div>
<label for="AccommodationType">Type:</label>
<input type="number" step="1" id="accommodationType" name="accommodation_type" value="0">
</div>
<div>
<button type="button" id="add_accommodation">Add Accommodation</button>
</div>
</div>
<script>
$( document ).ready(function() {
$('#add_accommodation').click(function() {
make_accommodation(this);
});
});
function make_accommodation(input) {
var value = {
type : $("#AccommodationType").val(),
};
var accommodation = $('#Accommodation').attr('id', 'accommodation');
accommodation.push(value);
console.log(accommodation);
}
</script>
At my end point I want the result to be and array (accommodation = [{1},{2},{3},{4}]). How can I do this?
Give the form an id, and just append a new hidden(?) input that has a name that has [] at the end of it, it will send the values as an array to the server.
HTML
<form id="myform" ...>
Javascript
function make_accommodation(){
var newInput = $("<input>",{
type:"hidden",
name:"accommodation[]",
value: {
type: $("#AccommodationType").val()
}
});
$("#myform").append(newInput);
}
Also you list the output as [1,2,3,4] but your code shows you setting the value as an object with a property type and setting it to the value of the accommodation input, i am going to assume that was a mistake. If I am mistaken just modify the value property in the code above.
Also in your code you change the id of the input, not sure why you were doing that as it serves no purpose and would have made your code error out so i removed it.
EDIT
Since you are wanting to send an array of objects, you will have to JSON.stringify the array on the client end and decode it on the server end. In this one you do not need multiple inputs, but a single one to contain the stringified data.
var accommodationData = [];
function make_accommodation(){
accommodationData.push({
type: $("#AccommodationType").val()
});
$("#accommodation").val( JSON.stringify(accommodationData) );
}
Then on the server you have to decode, not sure what server language you are using so i am showing example in PHP
$data = json_decode( $_POST['accommodation'] );
If you are using jQuery's ajax method you could simplify this by sending the array data
jQuery.ajax({
url:"yourURLhere",
type:"post"
data:{
accomodation:accommodationData
},
success:function(response){
//whatever here
}
});
Add antorher hidden field in form
<input type="hidden" name="accommodation[]"> // click1
<input type="hidden" name="accommodation[]"> // click2
...
<input type="hidden" name="accommodation[]"> // clickn
Then when you submit form on server you will have array of accommodation.
JS part :
function make_accommodation() {
$(document.createElement('input'))
.attr('type', 'hidden')
.attr('name', 'accommodation[]')
.val($("#AccommodationType").val())
.appendTo('form');
}
on server(PHP) :
print_r($_POST['accommodation']);
Since you're using jQuery you can create a function which creates another hidden field, after clicking on the button
<div id='acommodation-wrapper'></div>
<button type="button" id="add_accommodation" onclick="addAnother()">Add Accommodation</button>
<script type="text/javascript">
function addAnother(){
var accWrapper = $('#accommodation-wrapper');
var count = accWrapper.children().length;
var div = "<input type=\"hidden\" class=\"accommodation-"+count+"\" name=\"accommodation["+count+"]\"></div>";
accWrapper.append(div);
}
</script>

Best way to pass JS/ css info to a form

I am sure this is so easy and I'm just a huge huge noob. I have a form on a PHP page, and it has a few normal form elements (1 textarea, 1 text field).
I am also dynamically adding 100 small images to the page, which are random, and I am using JQuery to let someone select or deselect these images:
Here is the html that loops 100 times to display the images:
<div class='avatar'><img class='avatar_image' src='$this_profile_image' name='$thisfriend'></div>
and here is the Jquery:
<script type="text/javascript">
$(document).ready(function() {
$(".avatar_image").click(function() {
$(this).toggleClass("red");
});
});
</script>
What I want to do is, when the form is submitted, have the script that processes it be able to tell which of those 100 images is selected (so it's class will be "red" instead of "avatar_image"). I am blanking on this.
You'll need to add hidden inputs with some kind of identifiers for those images, and toggle the state of those inputs based on the image selected-ness. Something like this:
Change your image markup:
<div class='avatar'>
<img class='avatar_image' src='$this_profile_image' name='$thisfriend'>
<input type="hidden" name="avatar_image[]" value="$this_profile_image" disabled="disabled" />
</div>
Change jQuery binding (and use event delegation, maybe pick a better container than document.body):
<script type="text/javascript">
$(function() {
var selClass = 'red';
$(document.body).on('click', ".avatar_image", function() {
var $this = $(this);
var $inp = $this.siblings('input[type="hidden"]');
var isSelected = $this.hasClass(selClass), willBeSelected = !isSelected;
$this.toggleClass(selClass);
if(willBeSelected) {
$inp.removeAttr('disabled');
} else {
$inp.attr('disabled', 'disabled');
}
});
});
</script>
Read the submitted data in PHP (assuming you're submitting via a POST form):
$selectedImages = $_POST['avatar_image'];
Add a ID to each image, when its clicked grab the id and then inject it into a hidden textfield
<input type="hidden" name="avatar" id="avatar" value="" />
$(".avatar_image").click(function() {
$(this).toggleClass("red");
//assign its id to the hidden field value
$("input[name='avatar']").attr('value', $(this).attr('id'));
// pass that to your DB
});
I presume your using ajax to grab this data back
success : function(callback){
$("image[id*='"+callback.avatar+"']").addClass('red');
}
Try this
PHP: Add the id for the friend to the html you had
<div class='avatar'>
<img class='avatar_image' src='$this_profile_image' name='$thisfriend' data-id='$thisFriendsId>
</div>
JS: Create an empty array. Use each function to go through push the selected id into your array. Then use post to submit to your php.
selected = [];
$(function(){
$(".avatar_image").click(function() {
$(this).toggleClass("red");
});
$('.submit').click(function(){
$('.red').each(function(){
var selectedId = $(this).data('id');
selected.push(selectedId);
});
$.post ('http://mysite.com/process.php', selected, function() { alert('succes!'); });
});
​});​

Submitting a dynamic form using jQuery and AJAX

I am cloning a HTML drop down list using jQuery, the problem I have now is that there is no limit to the amount of cloned sections, and I have to capture all of the sections into a mySQL database.
How can I get all of those different sections with different ID's into a mySQL table, since I am using POST, how will the receiving PHP file know what variables to get from the header, and how do I get each cloned section to be it's own entry in the mySQL table?
my Javascript/jQuery:
$("span.remove").live('click', function(){
$(this).closest("div.container").fadeOut(400, function(){
$(this).remove();
$('#button').attr('disabled','');
});
});
//initialize the button
$('#button').attr('disabled','');
$('#button').click(function(){
var count = $("#systems_wrapper > .container").size();
var lastID = $("#systems_wrapper > .container:last").attr('id');
var exploded = lastID.split("_");
var increment = Number(exploded[1])+1;
if(count >= 5){
$('#button').attr('disabled','disabled');
}else {
$('#button').attr('disabled','');
}
var test = $('#systems_0.container').clone().attr('id', 'system_' + increment).appendTo('#systems_wrapper');
test.children(':nth-child(2)').append('<span class="remove"></span>');
test.children(':nth-child(2)').children(':first').attr('id', 'mail_' + increment);
});
//get the JSON object returned from test_post.php and run the necessary functions on the returned data
$.getJSON("test_post.php", function(data){
//clean out the select list
$('#box').html('');
//run the for loop to populate the drop down list
$.each(data, function(i, products) {
$('#box').append(
$('<option></option>').html(products.products)
);
});
});
HTML:
<h3>System Information:</h3>
<!-- Systems -->
<div id="systems_wrapper">
<div class="container" id="systems_0">
<label for="systems">Systems: </label>
<div>
<select id="box">
<option>Select one</option>
</select>
</div>
</div>
</div>
<div class="container">
<input type="button" id="button" name="button" value="add a system" />
</div>
This one has really stumped me, any help would be appreciated!
Thanx in advance!
You could pass an object via $.post(). But first, when you are cloning let the clone has a variable(as a property) containing some kind of id.
$('#systems_0.container').clone().attr('id', 'system_' + increment).appendTo('#systems_wrapper')[0].myID=increment;
postData={},sections=$('div[id^=systems_]');
sections.each(function(i){
var id=this.myID,self=$(this);
//for example, choose what to store here.
postData[id]=$('select#box option',self).toArray();
});
//posting
$.post('yourServerSideScript.php', postData,function(data){ console.log(data); });
Now your php predefined $_POST should be an array of ['1'=>[...], '2'=>[...], ...] and so on.

Categories

Resources