Angular Javascript inside php foreach inside HTML - php

I am trying to make a simple shopping website using mainly PHP and HTML.
Inside PHP, I created objects from a class, and those objects are in array.
Now inside HTML, I am printing each object's photo and name using PHP's foreach.
Since this is a shopping website, I have added a FORM under each item photo where the customer can type in the number of the items they wish to purchase. The default value is 0.
Now, using angularJS, What I want to do is:
1)when the value(the number of the items they want) is 0, nothing happens and the webpage prints nothing.
2)when the value is more than 0, print the number * the price right next to the form, so the user can see in real time how much the total is going to be for that specific item.
Here is my code..
<?php
class Stock{
public $name; //in real program it is private.
public $price;
}
//Create objects and initialize them by giving each of them name and price
//Assume there are 3 objects
$items = array($object1, $object2, $object3);
?>
//now in HTML code
<form method="POST" action="order.php">
<?php foreach($items as $item): ?>
<!--Print name and price of each -->
<input type="text" value="0" name="<?php echo $item->name; ?>"> {{ <!--*****--> }}
<?php endforeach ?>
I want to print the product of the number * price of the item right next to the form only if the value is greater than 0. I tried adding ng-model="quantity" inside input tag and wrote {{ quantity * $_POST[$item->name] }}. However, this does not fully work. This does print the product, but because it is inside foreach, when I change the value in the form for an item, the values for the other items' form change along with it. How can you apply angularJS only for the specific item?

Your loop must be in angular to do this.
So you could bind it as a model ..
FORM.PHP
<div ng-app="appModule">
<form action="order.php" method="post" ng-controller="orderFormController">
<div ng-repeat="item in itemList">
{{ item.name }} (price - {{ item.price }}): <input type="text" value="0" name="{{item.name}}" ng-model="qty[item.name]" />
Total: <span ng-if="qty[item.name] > 0">{{ item.price*qty[item.name] }}</span>
</div>
</form>
</div>
MODULE.JS
var app = angular.module("appModule", []);
app.controller("orderFormController", function($scope) {
// $scope.itemList - ajax your item list here
$scope.itemList = [
{name: 'Pencil', 'price': 10},
{name: 'Paper', 'price': 2},
{name: 'Folder', 'price': 13},
];
});

Change the value inside the input tag. Refer to HTML input value Attribute on W3 Schools.
<input value='<?php // your php code ?>' />
input value w3c schools
input value w3c schools example

Related

show form-control only when value chosen on previous form-control with html and php

I am creating a webpage with from-controls (2 in this exemple).
My code is the following :
<body>
<div class="option_choice_global">
Select your options
<div class="col-xs-2">
<label> Application </label>
<select class="form-control" id="application">
<?php
$applications = get_apps();
foreach ($applications as $key => $value) { echo '<option value='.$key.'>'.$value.'</option>'; }
?>
</select>
</div>
<div class="col-xs-1">
<label> Version </label>
<select class="form-control" id="version">
<?php
$versions = get_versions();
foreach ($versions as $key => $value) { echo '<option value='.$key.'>'.$value.'</option>'; }
?>
</select>
</div>
<div class="col-xs-12">
<button type="submit" class="btn btn-default" onclick="fonction_submit_graph(this)"> <b> Submit </b> </button>
</div>
</div>
</body>
But I would like the second one (the version) to appear only when a value on the first controller (the application) is chosen. And my function get_versions() will then depend on the selected application : get_versions(application_number).
How can I do to show the second controller only when a value on the first one is selected ? And to get the selected value ?
Thank you!
If I understand you right, you want to show the second select dropdown after a value is chosen from the first.
This can easily be done with JavaScript and CSS:
In the second select tag, add these attributes: style="{display: none;}". This will hide the dropdown. Also give it id="select2" for easy identification.
In the first select tag, add this attribute: onchange=showHiddenSelect(); This causes a function to be called when the value changes ie an option is selected. Also give it an id="select1".
Somewhere in your document, define the showHiddenSelect function like this:
function showHiddenSelect() {
document.getElementById("select2").style.display="block";
}
If you also wish to get the selected value, you'd just add this in that function: var select1value = document.getElementById("select1").value; and do what you want with it.
If you need the selected option from select1 to be sent to a backend and then used to calculate the options for select2, then your best bet would be to use AJAX to send and receive data from a script and then populate the select with JavaScript.

laravel 4 - Input old for arrayed checkbox

I have a loop of checkboxes with multiple attributes. One content may have many attributes, so user can check more than one attribute.
If some validation errors occurs in this form I need to pre-fetch already checked attribute.
#foreach($attributes as $entry)
<div class="check-line">
<input type="checkbox" id="cat4" class='icheck-me'
name="attribute[<?php echo $entry->id; ?>]"
data-skin="square"
data-color="blue"
value="{{$entry->id}}"
<?php
if(Input::old('attribute['.$entry->id.']')== $entry->id) {
echo 'checked="checked"';
}
?>
/>
<label class='inline' for="cat4">
<strong>{{$entry->name}}</strong>
</label>
</div>
#endforeach
I tried above but no luck.. any ideas?
From Laravel docs on Requests:
"When working on forms with "array" inputs, you may use dot notation to access the arrays:"
$input = Input::get('products.0.name');
So you should be able to do this fpr Input::old() as well:
<?php
if(Input::old('attribute.' . $ii) == $entry->id) {
echo 'checked="checked"';
}
?>
A slightly more catch-all answer to this would be to do an array search rather than just checking the current index. As such, I see the code looking like this:
#foreach($attributes as $entry)
<div class="check-line">
<input type="checkbox" id="cat4_{{{ $entry->id }}}" class="icheck-me"
name="attribute[]"
data-skin="square"
data-color="blue"
value="{{{ $entry->id }}}"
#if (in_array($entry->id, Input::old('attribute')))
checked
#endif
/>
<label class="inline" for="cat4_{{{ $entry->id }}}">
<strong>{{{ $entry->name }}}</strong>
</label>
</div>
#endforeach
So first off I've made the code more Blade-compliant:
Any echos are now {{{ and }}} rather than the previous mix of <?php echo ___; ?> and {{/}} (I went for {{{ rather than {{ as it's not HTML being echoed and it's better to be safer)
The <?php if () { is now a Blade #if ()
The name attribute is now just a standard array (doesn't include indices, as it doesn't need to), however the id attribute previously gave all checkboxes the same ID. While browsers will let you do this, it's technically illegal HTML, so I've appended the entry ID to each checkbox.
Finally, the if condition no longer checks that the value of the input with the current index matches the current entry's ID, but instead searches to see if the current entry's ID is anywhere in the returned array. This protects against the possibility of your entries being returned in a different order to the previous time they were on the page.
We now don't have a reliance on the $ii variable, so it can be removed too.
Caveats:
In doing this I've made the code a little nicer, but the code is no longer identical. Without knowing exactly why you use the $ii variable in order to provide keys to your attribute array I can't say that using my code will work correctly. However, assuming it was just there to help with this old input thing, then it's fine.
Also, my change of {{ to {{{ may have consequence I don't know about. I'd have thought for the $entry->id stuff it'd be fine, but maybe $entry->name in the <label> need to be unescaped HTML for a reason. Feel free to change this back.

Show one row of data, click next, hide original row and show next row... and so on

I'm using the http://www.advancedcustomfields.com plugin to create custom fields in Wordpress. I'm specifically using the repeater field functionality.
On a page I have a repeater that has an unlimited amount of rows. The usual way of echoing out all the data is the following:
<?php $counter = 1; if(get_field('step_by_step_training')): ?>
<?php while(the_repeater_field('step_by_step_training')): ?>
<p class="training-<?php echo $counter; ?>"><?php the_sub_field('introduction'); ?></p>
<?php $counter++; endwhile; ?>
<?php endif; ?>
Is it possible to show one row of data at a time with a next button that when pressed will show the next row of data? I only want one row of data showing at a time so if row 1 is originally showing, when next is clicked it hides row 1 and shows row 2. Essentially creating a step by step process.
Eventually I'd like to include a form so the user can submit data.
UPDATE:
<form class="form" method="POST" action="<?php the_permalink(); ?>">
<?php $counter = 1; if(get_field('step_by_step_training')): ?>
<?php while(the_repeater_field('step_by_step_training')): ?>
<div class="form-row">
<p class="training"><?php echo the_sub_field('introduction'); ?></p>
<button class="next">Next Form Element</button>
</div>
<?php $counter++; endwhile; ?>
<?php endif; ?>
</form>
<script type="text/javascript">
jQuery(function($) {
$(document).ready(function() {
// hide all form-rows, but not the first one
$('.form-row').not(':first').hide();
$('button.next').click(function(e) {
// prevent the next buttons from submitting the form
e.preventDefault();
// hide this form-row, and show the next one
$(this).parent('div.form-row').hide().next('div.form-row').show();
});
});
});
</script>
You could do something simple like this using jQuery (I think this is what you wanted?):
$(document).ready(function() {
// prepend a 'previous' button to all form-rows except the first
$('<button>').addClass('previous').text('Previous').prependTo($('.form-row').not(':first'));
// hide all form-rows, but not the first one
$('.form-row').not(':first').hide();
// add the submit button to the last form-row
$('<input>').prop('type', 'submit').val('Submit Form').appendTo($('.form-row:last'));
// handle the previous button, we need to use 'on' here as the
// previous buttons don't exist in the dom at page load
$('.form-row').on('click', 'button.previous', function(e) {
e.preventDefault();
$(this).parent('div.form-row').hide().prev('div.form-row').show();
});
$('button.next').click(function(e) {
// prevent the next buttons from submitting the form
e.preventDefault();
// hide this form-row, and show the next one
$(this).parent('div.form-row').hide().next('div.form-row').show();
});
});
some example markup:
<form action="index.php" method="post">
<div class="form-row">
<label for="forename">Forename</label>
<input type="text" name="forename" />
<button class="next">Next Form Element</button>
</div>
<div class="form-row">
<label for="forename">Surname</label>
<input type="text" name="surname" />
<div style="clear: both;"></div>
<label for="another">Another</label>
<input type="text" name="another" />
<button class="next">Next Form Element</button>
</div>
<div class="form-row">
<label for="last">Last Form Element</label>
<input type="text" name="last" />
</div>
</form>
You can add as many form elements to each form-row as you want, here's a fiddle to play with
edit
Things to note here are that the previous buttons are injected to the DOM dynamically, and so is the forms submit button (notice how I've removed it from the last form-row in the markup)
Here's an updated fiddle
You could start with a jQuery accordion menu. Some CSS will allow you to minimize the real estate occupied by the deselected rows. If you want to actually discard and retrieve certain rows based on some identifiable characteristic (for instance, ID number), you'll need to go with AJAX.
You could write your own custom method with something like JQuery.
Assign a class to each row, and keep track of which one is selected, when viewing another row simply .hide() the one that was showing and .show() the one you wish to display.
If you want to keep your HTML cleaner, you could use the JQuery .data() functionality to assign identifiers to each element and refer to them that way as well.
Most of this all depends on your constraints with wordpress, how it looks & your actual HTML layout
After it's all written to the screen, can't you just hide everything but the first row? And then each time you click the button, have it hide everything and show the next row. Try using jquery's next() function. jquery - next()
Ah, looks like deifwud beat me to it with a better explanation.

Farbtastic is broken and wont update my input fields

So, I have a foreach loop creating a bunch of form fields to allow users to use farbtastic to select colors for font and such. The loop creates fields for probably 60 fields and while the colorpicking works, for whatever reason after 20 fields farbtastic stops updating the input fields with the hexcode. It changes the input field background colors but it doesn't update the field.
What's even more weird, is that all these fields are in separate tabs, and the way wordpress handles tabs is by putting each on a new page. So the page has to reload. So once you get to the later tabs (and therefore later fields) one of two of the fields will work correctly but most do not. So like, field 2 on one tab works ok, but the same field on a different tab does not.
Right now I have a single jQuery method controlling the color picker:
// Color Picker for js file
jQuery('.pickcolor').click( function(e) {
colorPicker = jQuery(this).next('div');
input = jQuery(this).prev('input');
jQuery(colorPicker).farbtastic(input);
colorPicker.show();
e.preventDefault();
jQuery(document).mousedown( function() {
jQuery(colorPicker).hide();
});
});
and the form fields pretty much all look like this:
$name is the section name and $element is the thing the color is being chosen form (nested foreach loop)
<div class="color_option option" style="position: relative;">
<label for="<?php echo $name; ?>_fonts"><?php echo $elementName;?> Color</label>
<input class="link_color" type="text" id="<?php echo $name; ?>_fonts"
name="kjd_<?php echo $name;?>_settings[kjd_<?php echo $name; ?>_fonts][<?php echo $element; ?>]"
value="<?php echo $options['kjd_'.$name.'_fonts'][$element] ? $options['kjd_'.$name.'_fonts'][$element] : ''; ?>"
style="background:<?php echo $options['kjd_'.$name.'_fonts'][$element]?>; color:<?php echo $options['kjd_'.$name.'_fonts'][$element]?>;"
/>
<input type='button' class='pickcolor button-secondary' value='Select Color'>
<div style="position: absolute;" class="colorpicker"></div>
So the jQuery looks right, but I wonder if I should dynamically create the jquery in the foreach loop to target each field by ID
I solved it kinda of.
value="<?php echo $options['kjd_'.$name.'_fonts'][$element] ? $options['kjd_'.$name.'_fonts'][$element] : ''; ?>
the last part of that if-statement cant be empty, it has to be ' ' (blank space), rather, in order for farbtastic to update the input there has to be some value in there. so I used 'none' to avoid confusing users.
my code now says
value="<?php echo $options['kjd_'.$name.'_fonts'][$element] ? $options['kjd_'.$name.'_fonts'][$element] : 'none'; ?>

Dynamically Setting Value With JQuery

I have a table of assignments. Within each row is a cell, that when clicked will bring up a hidden div to the right of the table. Within the div is a form that allows a user to associate a selected document with a task.
Currently the table is generated, in part, by a PHP "for" loop; I am cycling through an array and creating a new table row for each array index.
Within each row there are two table cells. I want the contents of one of the cells to be a hyperlink that, when clicked, will display a hidden div. Within the hidden div will be a form. The form will have a hidden input box, and I would like to dynamically set this value when the hyperlink is clicked.
Here is a sample of the table:
<table>
<tr>
<th>Task</th>
<th></th>
</tr>
<?php
for($i=0; $i<sizeof($task_array); $i++)
{ ?>
<tr>
<td><?php echo $task_array[$i]['task'];?></td>
<td>Attach Doc</td>
</tr>
}
?>
</table>
Here is the hidden div and form:
<div id="hidden_div">
<form action="[url]" method="post" enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="file" id="file" />
<input type="hidden" id="task_id" value="">
<input type="submit" name="submit" value="Submit" />
</form>
</div>
I know that I can do the following with JQuery to display the hidden div:
$("#hiddendiv").show();
I also know that the hidden field 'task_id' can be set with JQuery by using
$("#task_id").val() = 'some value';
The problem I am having is that, since the values are coming from an array, I'm not sure how to specify a specific value. For example, the value of a task id is found in the variable $task_array[$i]['task_id']. I could try this:
$('#show_div').click(function(){
$("#hiddendiv").show();
$("#task_id").val() = ???
});
I'm sort of stuck on specifying for which iteration to use the task id value.
My apologies if that wasn't very clear. Any help would be appreciated. Thanks.
PHP
<?php
for($i=0; $i<sizeof($task_array); $i++)
{ ?>
<tr data-task-id="<?php echo $task_array[$i]['task_id'];?>">
<td><?php echo $task_array[$i]['task'];?></td>
<td>Attach Doc</td>
</tr>
}
?>
See that I added a data-attribute named data-task-id to the tr elements that stores the task_id for that row. We can use this in a click event handler later.
JS
//bind an event handler to the `tr` elements for the `click` event to show the `tr`s children elements (the `td`s)
$('tr').on('click', function () {
$(this).children().show();
//this next line is how we get the `task_id` associated with a row
$(this).attr('data-task-id');
});
//since we bound an event handler to the `tr` elements for the `click` event it's a good idea to stop the propagation of click events on links within the `tr` elements so the event doesn't bubble up the the `tr` elements
$('tr').find('a').on('click', function (event) {
event.stopPropagation();
});
Note that .on() is new in jQuery 1.7 and in this case is the same as .bind().
Also, you need to change the #show_div element's ID for each element (IDs must be unique). I recommend just changing it to a class instead of using an id:
<td>Attach Doc</td>
Then you can bind an event handler to it like this:
$('.show_div').click(function(){
$("#hiddendiv").show();
$("#task_id").val($(this).parents('tr').eq(0).attr('data-task-id'));
});

Categories