I have this code that loops through a HTML structure and builds an array based on its data attributes. I want to execute a conditional statement within a foreach loop and want to check if my count variable is within the array. I looked at inArray() but I'm not sure it works with associative arrays?
Here is the HTML
<div class="dfp" data-adposition="<?php echo $dfpPos; ?>" data-dfpcode='<?php echo $dfpCode; ?>'>
</div>
<div class="dfp" data-adposition="<?php echo $dfpHalfPos; ?>" data-dfpcode='<?php echo $dfpHalfCode; ?>'>
</div>
Here is the JS that builds the array.
var dfpObj = { "adverts" : [] };
$(".dfp").each(function(){ // PROCESS DFPS
var code = $(this).data("dfpcode");
var position = $(this).data("adposition");
var dfp = {
"code": code,
"position": position
}
dfpObj.adverts.push(dfp);
});
And my IF statement.
if($.inArray(count, dfpObj.adverts) !== -1) {
var dfp = $('.dfp[data-adposition=' + count + ']');
var dfpcode = $(dfp).data("dfpcode");
var dfppos = $(dfp).data("adposition");
myfunction(dfpcode, dfppos);
}
// count is within a foreach loop so at the end of the loop is $count++
You can use the following.
$.grep(dfpObj.adverts, function(obj) { return obj.code == "122"; })
This will give you that object or else gives you empty array.
Related
This is my second topics
so i am trying to insert array data with input tag.
I am make the tag input with an jquery
<input type="button" class="btn btn-primary" onclick="steps(); return false;" value="Add steps">
function steps() {
var idf = document.getElementById("idf").value;
var stre;
stre="<p id='srow" + idf + "'><input type='text' class='haha{{ $errors->has('steps') ? ' is-invalid' : '' }}' name='steps[]' id='steps' /> <a href='#' style=\"color:#3399FD;\" onclick='hapusElemen(\"#srow" + idf + "\"); return false;'>Hapus</a></p>";
$("#divHobi").append(stre);
idf = (idf-1) + 2;
document.getElementById("idf").value = idf;
}
function hapusElemen(idf) {
$(idf).remove();
}
also this result after input data with dd()
array:3 [0 => "banget"
1 => "asd"
2 => "wwww"
]
at this case i am trying to input that array to database and that work
this is the code
$hitung = $req->steps;
$hitung2 = count($hitung);
dd($hitung);
for ($i=0; $i < $hitung2; $i++) {
$user = new TestCase;
$user->id_test_case = $req->id_test_case;
$user->id_document = $req->id_document;
$user->test_scenario = $req->test_scenario;
$user->post_condition = $req->post_condition;
$user->pre_condition = $req->pre_condition;
$user->expected_result = $req->expected_result;
$user->steps = $req->steps[$i];
$user->actual_result = $req->actual_result;
$user->status = $req->status;
$user->save();
}
but the result is be like
and then the expected result that i hope is be like
so is that possible to make it? without the loop?
You're creating a new TestCase in every loop; so of course you're going to end up with 3 rows in your table. Get rid of the loop and use implode() to set steps as a string:
$user = new TestCase;
$user->id_test_case = $req->id_test_case;
$user->id_document = $req->id_document;
$user->test_scenario = $req->test_scenario;
$user->post_condition = $req->post_condition;
$user->pre_condition = $req->pre_condition;
$user->expected_result = $req->expected_result;
$user->steps = implode(",", $req->steps);
$user->actual_result = $req->actual_result;
$user->status = $req->status;
$user->save();
Now saving an array into a database as a CSV value isn't necessarily the best approach, so be aware that you may run into limitations based on that decision. Consider using a pivot approach (users, steps, users_steps) or similar.
I have two JSON arrays coming from an external website. I sort and merge the two arrays, decode them and then sort them from highest to lowest by ID.
Currently, when the option 'alphabetical' is clicked, ?sort=alphabetical is added onto the end of the URL and when the page has finished reloading, the JSON arrays are once again decoded and merged.
This is not my desired outcome: I do not want the JSON arrays to be decoded and merged again when the option is clicked - I simply want the already decoded and merged JSON arrays to be sorted alphabetically.
Arrays:
$homepage = array();
$homepage[]= '{
"info":{
"collection":[
{
"Name":"Charlie",
"ID":"7"
},
{
"Name":"Emma",
"ID":"9"
}
]
}
}';
$homepage[] = '{
"info":{
"collection":[
{
"Name":"Bob",
"ID":"5"
}
]
}
}';
Sorting:
$data = array();
foreach ($homepage as $homepage2) {
$tmp=json_decode($homepage2, false);
$data = array_merge($data,$tmp->info->collection);
}
if(!empty($_GET['sort']) && $_GET['sort'] == 'alphabetical') {
usort($data, function ($a, $b) {
return strcmp($a->Name, $b->Name);
});
}else{
usort($data, function ($a, $b) {
return $b->ID - $a->ID;
});
}
echo'
<select onchange="location.href = this.value;">
<option value="example.php?sort=alphabetical">Alphabetical</option>
</select>
';
foreach($data as $key) {
echo'
<a href="test.com">
<p>'.$key->ID.'</p>
<p>'.$key->Name.'</p>
</a>
';
}
You could use JavaScript for doing the sorting on click, and use PHP only for passing the JSON to it.
After you provided the HTML structure you want to display the list in, I updated this answer to use div elements for the records and p elements for the fields.
We could replace the select list, for selecting the sort order, by two buttons.
Here is the PHP code:
<?php
$homepage = array();
$homepage[]= '{
"info":{
"collection":[
{
"Name":"Charlie",
"ID":"13"
},
{
"Name":"Emma",
"ID":"9"
}
]
}
}';
$homepage[] = '{
"info":{
"collection":[
{
"Name":"Bob",
"ID":"10"
}
]
}
}';
$data = array();
foreach ($homepage as $homepage2) {
$tmp=json_decode($homepage2, false);
$data = array_merge($data,$tmp->info->collection);
}
?>
<div id="container"></div>
<button id="sort1">Alphabetical</button>
<button id="sort2">High to Low</button>
<script>
var collection = <?=json_encode($data)?>;
function populate(compareFunc) {
collection.sort(compareFunc);
var container = document.getElementById('container');
container.innerHTML = '';
collection.forEach(function (key) {
var div = document.createElement("div");
div.className = "inventory";
var span = document.createElement("span");
span.textContent = key.ID;
div.appendChild(span);
span = document.createElement("span");
span.textContent = key.Name;
div.appendChild(span);
container.appendChild(div);
});
}
var populateById = populate.bind(null, function (a, b) {
return a.ID - b.ID;
});
var populateByName = populate.bind(null, function (a, b) {
return a.Name.localeCompare(b.Name);
});
document.getElementById("sort1").addEventListener('click', populateByName);
document.getElementById("sort2").addEventListener('click', populateById);
document.addEventListener('DOMContentLoaded', populateById);
</script>
For the sample data this will result in the following JavaScript/HTML, which you can test here:
var collection = [{"Name":"Charlie","ID":"13"},{"Name":"Emma","ID":"9"},{"Name":"Bob","ID":"10"}];
function populate(compareFunc) {
collection.sort(compareFunc);
var container = document.getElementById('container');
container.innerHTML = '';
collection.forEach(function (key) {
var div = document.createElement("div");
div.className = "inventory";
var span = document.createElement("span");
span.textContent = key.ID;
div.appendChild(span);
span = document.createElement("span");
span.textContent = key.Name;
div.appendChild(span);
container.appendChild(div);
});
}
var populateById = populate.bind(null, function (a, b) {
return a.ID - b.ID;
});
var populateByName = populate.bind(null, function (a, b) {
return a.Name.localeCompare(b.Name);
});
document.getElementById("sort1").addEventListener('click', populateByName);
document.getElementById("sort2").addEventListener('click', populateById);
document.addEventListener('DOMContentLoaded', populateById);
span { margin-left: 5px }
div.inventory { border-bottom: 1px solid gray }
<div id="container"></div>
<button id="sort1">Alphabetical</button>
<button id="sort2">High to Low</button>
Note that I gave the three items different ID values than in your question, since otherwise the sort order would be the same for both ID and Name.
Using tables: alternative
There are nice JavaScript libraries which give much more features to represent data sets. Here is an example using jQuery with DataTables:
var collection = [{"Name":"Charlie","ID":"13"},{"Name":"Emma","ID":"9"},{"Name":"Bob","ID":"5"}];
function populate() {
var tbody = $('#collection>tbody');
collection.forEach(function (key) {
var row = $('<tr>');
row.append($('<td>').text(key.ID));
row.append($('<td>').text(key.Name));
tbody.append(row);
});
}
$(document).ready(function(){
populate();
$('#collection').DataTable();
});
<script src="http://code.jquery.com/jquery-1.12.3.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.12/css/jquery.dataTables.min.css">
<script src="https://cdn.datatables.net/1.10.12/js/jquery.dataTables.min.js"></script>
<table id="collection">
<thead>
<tr><th>ID</th><th>Name</th></tr>
</thead>
<tbody/>
</table>
The actual code is even smaller (not counting the included library) than a pure JavaScript solution would be with a basic table. But this has sorting up and down, filtering, pagination, nice styles, ...
There are several alternatives for this answer, so I will present a simple one:
Send the data already sorted, a default one, if the user made no choices. Then, set a function that sorts the data as needed, and redraws tables/divs/whatever you are using to present them.
As an quick example:
function sortAlpha(){
for each (stuff in data){
document.getElementById("aTable").textContent=data.StringRepresentation;
}
}
Then a function for sortSize, sortEtc, etc... in each function, you clear a div content, and populate it again. This way, you do not need to request new content from servers
getElementById documentation
There are multiple solutions in which you can achieve the desired results. If you want it pure PHP way what you can do is save the data in PHP Sessions and retrive them as need.
Here is the trick comes, You create function to get the result data in which you pass single parameter whether you want to get the data from external URL or from your saved data.
Now, in your application whenever you want to refresh the saved data call the same function with parameter denoting to refresh the saved data in SESSIONS to get replaced with data from external source.
Using this method you can reuse the data you've already fetched from external source without re-fetching it every-time you reload the function.
You can make another function which will return true for all cases in which application has to re-fetch the resultset from external source.
I've written pseudo code for you to understand what I'm trying to convey,
Function check whether we've to re-fetch the result from external source:
function hasToRefreshResult() {
if(/* CERTAIN CONDITIONS */) {
return true;
}
return false;
}
Couple of functions to get the data from local/external source according to the parameter passed:
function getResultArray($getdatafromlocal) {
if(!hasToRefreshResult() && $getdatafromlocal && array_key_exists("filertereddata",$_SESSION) && isset($_SESSION["filertereddata"])) {
$data=$_SESSION["filertereddata"];
} else {
$data=getDataFromExternalURL();
}
if(!empty($_GET['sort']) && $_GET['sort'] == 'alphabetical') {
usort($data, function ($a, $b) {
return strcmp($a->Name, $b->Name);
});
} else {
usort($data, function ($a, $b) {
return $b->ID - $a->ID;
});
}
return $data;
}
function getDataFromExternalURL() {
/*****
YOUR LOGIC TO GET DATA FROM EXTERNAL URL;
*****/
$data = array();
foreach ($homepage as $homepage2) {
$tmp=json_decode($homepage2, false);
$data = array_merge($data,$tmp->info->collection);
}
$_SESSION["filertereddata"]=$data;
return $data;
}
I hope this will solve your issue strictly using PHP.
Also don't forget the write session_start(); at the top of the PHP file you will be using this functions.
Going through the other posts i must either have something wrong with my code or my logic is fundamentally flawed.
So what happens is i have a series of array elements that get called/written, these array elements need to have sub elements modified by java script.
Everything was workign before i needed to add an array i.e i was using a single element selector ID for the functions below and got the correct results. However after adding unique ID's in a loop it doesn't want to change.
So here's what happens, I have a separate div that is hidden. This prints out how many elements are in the array as its a PHP session variable. $Carray is a count function and works correctly.
<div class="Carray"><?php echo $Carray;?></div>
Then as the items are looped they add an array ID
<?php
$arrayID = -1;
foreach($_SESSION['activity'] as $key){
foreach($key as $list){
$arrayID += 1;
?>
<div id="subP_<?php echo $arrayID;?>" class="booking_action">-</div>
<div id="booking_people_<?php echo $arrayID;?>" class="booking_people_number">
<?php echo $list["i_quantity"] ?>
</div>
<div id="addP_<?php echo $arrayID;?>" class="booking_action">+</div>
<?php }} ?>
Then in Javascript i call a loop function that counts through however many $Carray elements there are and then corresponds the correct function actions to the correct div ID's
//get the counted array variable and force as an int
var js_var = parseInt($('.Carray').html(),10);
// loop for however many array elements there are
for (i = 0; i < js_var; i++){
// get the amount of people from a field
var ppl_P = parseInt($('#booking_people_'+i).html(),10);
// subtract 1 person and then change the output to match the new people count
$("#subP_"+i).click(function() {
if(ppl_P >= 2){
ppl_P -= 1;
$('#booking_people_'+i]).html(ppl_P);
}
});
// Add 1 person and then change the output to match the new people count
$("#addP_"+i).click(function() {
ppl_P += 1;
$('#booking_people_'+i).html(ppl_P);
});
}
****************************** EDIT **********************
So based on Jimmi Elofsson answer which works beautifully, i want to expand this to effect elements that are not inside the parent/child selectors. The selector is '.booking_price_inner' which is another div stored elsewhere. I am assuming the line that needs the correct syntax is the marked line.
The '.booking_base_price' is within the parent/child element.
$(".subPerson").click(function() {
// Subtract Person
var subPeopleCount = getCurrentCountByPeopleItem($(this).parent()) - 1;
$(this).parent().children('.booking_people_number').html(subPeopleCount>1 ? subPeopleCount : 1);
//Change price
var totalPriceS = subPeopleCount * getBasePrice($(this).parent());
$(this).parent().children('.booking_price_inner').html(totalPriceS); <-------
});
$(".addPerson").click(function() {
//Add person
var addPeopeCount = getCurrentCountByPeopleItem($(this).parent()) + 1;
$(this).parent().children('.booking_people_number').html(addPeopeCount);
//Change price
var totalPriceA = addPeopleCount * getBasePrice($(this).parent());
$(this).parent().children('.booking_price_inner').html(totalPriceA); <------
});
// get the number of people in the specific array
function getCurrentCountByPeopleItem(peopleItem) {
return parseInt(peopleItem.children('.booking_people_number').html());
}
//get the base price
function getBasePrice(peoplePrice){
return parseInt(peoplePrice.children('.booking_base_price').html());
}
Markup
<div id="<?php echo $arrayID;?>" class="booking_people">
<div class="booking_date_header">People:</div>
<div class="subPerson booking_action">-</div>
<div class="booking_people_number"><?php echo $list["i_quantity"] ?></div>
<div class="addPerson booking_action">+</div>
<div class="booking_base_price"><?php echo $list["i_base_price"] ?></div>
</div>
<div class=spacer></div>
<div class=cost>
<div class=booking_price_inner></div>
</div>
If you don't mind, I did some changes in your code.
you could make your add/substract element use the same click function with the help of some DOM traversing. That way you wouldnt need the CArray to keep track of the buttons.
Javascript:
// subtract 1 person and then change the output to match the new people count
$(".subPerson").click(function() {
var subPeopleCount = getCurrentCountByPeopleItem($(this).parent()) - 1;// Substract by one.
$(this).parent().children('.booking_people_number').html(subPeopleCount>1 ? subPeopleCount : 1);
});
// Add 1 person and then change the output to match the new people count
$(".addPerson").click(function() {
var addPeopeCount = getCurrentCountByPeopleItem($(this).parent()) + 1; // Increase by one.
$(this).parent().children('.booking_people_number').html(addPeopeCount);
});
function getCurrentCountByPeopleItem(peopleItem) {
return parseInt(peopleItem.children('.booking_people_number').html());
}
PHP:
<?php
$arrayID = -1;
foreach($_SESSION['activity'] as $key){
foreach($key as $list){
$arrayID += 1;
?>
<div class="booking_people_item" id="<?php echo $arrayID;?>">
<div class="subPerson booking_action">-</div>
<div class="booking_people_number">
<?php echo $list["i_quantity"] ?>
</div>
<div class="addPerson booking_action">+</div>
</div>
<?php }} ?>
I added a div wrapper around your elements called booking_people_item.
from what I see - you're definig click functions in a loop. Those click functions have a reference to a ppl_P variable. When you define the click, it seems OK. But when the click is triggered, the ppl_P variable is already set to the value from loops last iteration. So, whenever you call that click function, it always has the same result, doesn't it?
The proper way to do it would be to pass this ppl_P variable as a parameter, so you don't have a reference to a variable that was already changed in the other scope. Something like:
function addClickFunction(i, ppl_P){
$("#subP_"+i).click(function() {
if(ppl_P >= 2){
ppl_P -= 1;
$('#booking_people_'+i]).html(ppl_P);
}
});
// Add 1 person and then change the output to match the new people count
$("#addP_"+i).click(function() {
ppl_P += 1;
$('#booking_people_'+i).html(ppl_P);
});
}
And then use this function inside the loop:
var ppl;
for (i = 0; i < js_var; i++){
ppl = parseInt($('#booking_people_'+i).html(),10);
addClickFunction(i, ppl);
}
This hasn't been tested, but I'm pretty sure you'll get the point :)
im trying to pass a php array to javascript function onload that will display the js array in a drop down list but now im already doing it for sometime i guess i need to pop it again
first i pass it from one php file to another using this code
header("location: Rules.php?varFields=".serialize($varFields));
secondly i transfer to another variable as it had been passed to the said php file
<?php
$varArray = unserialize($_GET['varFields']);
?>
third part is im tyring to pass it into a jS functon that will then display it to a drop down list
<body id="body" onclick="cmbRuleField(\'' + <?php echo json_encode($varArray);?> + '\');" >
and here is the external javascript code
function cmbRuleField(varArray)//ruleField
{
var varDisplay = JSON.stringify(varArray);
var sel = document.getElementById("ruleField") // find the drop down
for (var i in varDisplay)
{ // loop through all elements
var opt = document.createElement("option"); // Create the new element
opt.value = varDisplay [i]; // set the value
opt.text = varDisplay [i]; // set the text
sel.appendChild(opt); // add it to the select
}
}
for the first two part i already tested it and it is working but for the last parts i cant make it work
I think this part looks suspicious
<body id="body" onclick="cmbRuleField(\'' + <?php echo json_encode($varArray);?> + '\');" >
maybe
<body id="body" onclick="cmbRuleField(<?php echo json_encode($varArray);?>)">
is more like it.
One more tip, you can see the output on the rendered page to determine what the written out code looks like. So if you see something like:
<body id="body" onclick="cmbRuleField('['a', 'b']')">
you know there is a problem. You want a native Javascript array to be passed like this
<body id="body" onclick="cmbRuleField(['a', 'b'])">
EDIT
After talking on chat it became clear the top portion of OP's code needed a tweak as well.
header("location: Rules.php?varFields=".http_build_query($varFields));
The problem has to do with quotes not being terminated here:
...
<body id="body" onclick="cmbRuleField(\'' + <?php echo json_encode($varArray);?> + '\');" >
...
The JSON created using json_encode will have a lot of double quotes. Try this:
<script>
var array = <?php echo json_encode($varArray);?>;
</script>
<body id="body" onclick="cmbRuleField(array);">
There is a much easier way. Encode the $varArray as direct HTML options before sending to the browser. For instance:
<select id="ruleField">
<?php for ($i = 0; $i < count($varArray); $i++) { ?>
<option value="<?php= $varArray[$i].val ?>"><?php= $varArray[$i].name ?></option>
<?php } ?>
</select>
Might be because you are calling JSON.stringify on something that is already a string?
Also what is myCars?
..
for (var i in myCars)
..
Possibly rename it to varArray.
or rename varDisplay to varArray.
and lastly try calling JSON.parse instead:
function cmbRuleField(varArray)//ruleField
{
var varDisplay = JSON.parse(varArray);
var sel = document.getElementById("ruleField") // find the drop down
for (var i in myCars)
{ // loop through all elements
var opt = document.createElement("option"); // Create the new element
opt.value = varDisplay [i]; // set the value
opt.text = varDisplay [i]; // set the text
sel.appendChild(opt); // add it to the select
}
}
If that didn't work post the html output here so peeps can create a fiddle :)
I am reposting this question with revised code that use more of jQuery.
Here is the HTML code that defines the objects:
<LEGEND><b>Select Study Sample</b></LEGEND>
<p>
<P CLASS=select_header>Study - Box - Well - Lab ID<br>
<SELECT multiple size=20 NAME="stylabid" ID="stylabid" onchange=show_stylabid() onclick=clear_fetch() STYLE="width: 115px">
<?php
$i=0;
while ($i < $numstylabids) {
$styarr = pg_fetch_row($stylabidresult);
echo "<option value=$styarr[0]>$styarr[1]\n";
$i++;
}
?>
</select>
and
<LEGEND><b>Select Project Sample</b></LEGEND>
<p>
<P CLASS=select_header>Project - Box - Well - Lab ID<br>
<SELECT multiple size=20 NAME="pjtlabid" ID="pjtlabid" onchange=show_pjtlabid() onclick=clear_fetch() STYLE="width: 115px">
<?php
$j=0;
while ($j < $numpjtlabids) {
$pjtarr = pg_fetch_row($pjtlabidresult);
echo "<option value=$pjtarr[0]>$pjtarr[1]\n";
$j++;
}
?>
</select>
Now, here is the javascript; I am simply trying to get the values of the selected object, which can be either a Study or a Project. I use this later to retrieve data from the database:
function fetchgenotype() {
var ms, mndx, ss, sndex = 0;
ms = $("#marker")[0].selectedIndex;
if (Study_selected) {
ss = $("#stylabid")[0].selectedIndex;
sndx = $("#stylabid").val(ss);
} else
ss = $("#pjtlabid")[0].selectedIndex;
sndx = $("#pjtlabid").val(ss);
}
// for debugging...
alert('ss='+ss+', sndx='+sndx);
This code dies on the line sndx = ... Would really appreciate any help!
TIA
Currently i don't know what $("#marker") an Study_selected are.
Assuming there is anything OK so far, change the function into:
if (Study_selected) {
sndx = $("#stylabid").val();
} else
sndx = $("#pjtlabid").val();
}
val() returns the value of a form-element when used without an argument, otherwise it will set the value and return an jQuery-object.
There is no need to retrieve the selectedIndex, you may access the value of the select-element directly(it will be the value of the currently selected option)
I think you have a syntax error
sndx should be sndex .. or the other way around
var ms, mndx, ss, sndex = 0; // <--
$("#pjtlabid").val(ss) // <-- setter method
.val(value) is also a setter method so sndx is undefined because it never was defined with any value
It's a typo:
var ms, mndx, ss, sndex = 0;
should be
var ms, mndx, ss, sndx = 0;