I'm new to AngularJS and decided to try it out. As I read about it that I can simply plug into existing HTML and it will work. And now I'm stuck at this point.
Here is my shortened PHP code with wordpress and angularjs:
<?php
$the_query = new WP_Query(array('post_type' => 'products', 'nopaging' => 'true'));
<div class="container">
<?php while ($the_query->have_posts()) : $the_query->the_post(); ?>
<?php $name = get_field("name"); ?>
<?php $tree = get_field("tree"); ?>
<div class="material" ng-click="productMaterial(product)"
ng-init="product={name:'<?php echo $name; ?>',tree:'<?php echo $tree; ?>'};">
</div>
<?php endwhile; ?>
</div>
After the loop is done, then according to HTML source, all the ng-inits <div class="material">-s get the correct values:
<div class="material" ng-click="productMaterial(product)" ng-init="product={name:'Castello',tree:'oak'};"></div>
..
<div class="material" ng-click="productMaterial(product)" ng-init="product={name:'Variostep CL',tree:'oak'};"></div>
My controller:
calculator.controller('Calc1ProductController', ['$scope', 'calc1Service', function($scope, calc1Service) {
$scope.productMaterial = function(product) {
console.log("Clicked product: " + $scope.product.name); // print always Variostep CL
};
}]);
So the problem is that every time I click on any product, always the last product gets printed in console that is Variostep CL. I understand each new cycle in loop just overrides the previous product object and only the last product is stored.
How is it possible to pass the product data so, that whenever i click in webpage, the correct product data is logged to console?
As I have seen that other approach is to use pure angularjs approach, that I do the API request and receive JSON and then use instead of WP loop the ng-repeat, but then it will require me to rewrite even more code.
I was thinking to make an incrementing counter and store array of products and then access by the index in angular controller or maybe is there some simpler approach?
If my question is too messy, I can bring webpage snapshots and more clearer explanation. Thank you
Quoting from http://docs.angularjs.org/api/ng.directive:ngInit
The only appropriate use of ngInit is for aliasing special properties of ngRepeat, as seen in the demo below. Besides this case, you should use controllers rather than ngInit to initialize values on a scope.
But, since you are using Angular with PHP, I am not sure this suggestion still stands.
I think the reason why you are always seeing the last product is because you are continuously overriding the same piece of data in your controller with the ng-init declarations looped by the PHP code you have. In effect, your controller has actually defined $scope.product through your use of ng-init if I am not mistaken. So, all your ng-click calls will use the shared $scope.product as their arguments.
As a suggestion, if it is possible for you to acquire all your product data at once (i.e. as an array), you should do that instead, store the data to your controller, then make use of ng-repeat to have Angular create HTML for each piece of product data.
Related
<?php
<div class="someclass">
<ul class="someclass">
foreach ($this->showonline as $key => $friend) {
<li>
$friend['avatar'];
$friend['name'];
</li>
}
</ul>
</div>
?>
exmple :-
model.php
class.php
hook.php
index.phtml
with model i get database information. with class im calculating online friend list as a array using array_intersect. and with hook i render to index.phtml. in phtml i use foreach loop and get the result to my online friendlist.
Here is my function im getting online user list with this. but if new user come to online i must refresh the page to see new online member. i want to make it auto update list. with ajax or something. can someone give me example how can i do that?
You may use setTimeout function, either to reload the page or to call ajax and update the page content. here is small idea.
setTimeout(function(){
// Do code here for reload/ajax here.
}, 3000);
I believe the problem is more involved than merely front-end.
You will need the client to establish a socket with your server such that your server is able to constantly inform users of new online users. Otherwise, using a stay-alive connection with the server can also help, and use some jQuery to handle user list updates.
I am having a problem where I am successfully setting a URL variable in the form of mywebsite.com/contact/?product=VAR1 from one page to another, and it will be read on the 2nd page with my simple code.
First use is fine but any thing after that is not. There is a problem with the variable not being cleared/re-read/reset. The URL Bar even reads fine in the URL bar mywebsite.com/contact/?product=VAR2 so that first part works.
But the code doesn't want to get the VAR2 part once it has stored VAR1. It just keeps re-displaying VAR1 once it is loaded once.
<?php echo htmlentities($_GET['product']); ?>
If it makes a difference, I am succesfully displaying the ?product= information inside of a jQuery value changer with this:
$(".input-text").val('<?php echo htmlentities($_GET['product']); ?>');
I have tried my own solutions like putting in a unset($product); before the last ?> but no avail.
I have a limited knowledge of PHP/jQuery and would like to use this way of setting/grabbing variable since it is simple. I am using it in jQuery because it can re-write the exact form input-box value with this variable passed along, and successfully send it in my CMS's contact form.
------------------------ updated: added code ------------------------
(I am just displaying all the code logically as I can think of)
#1: Set up the variable into the URL. The first echo getURL displays the url, I add my ?product= and then it gets the item name. This is all fine.
<a href="<?php echo Mage::getURL('webforms/index/index/id/2') ?>?product=<?php echo $_product->getName(); ?>">
#2: My form is set up within my CMS. It has a special class so I can select it exactly within my jQuery. I do not have access to all of this, it is generated by the CMS. The purpose obviously is to get selected products to be rememmberd via this Variable, and serve purpose in the contact form.
<div class="field webforms-fields-enquiryfield">
<label for="field_20">
Product in Enquiry
</label>
<div class="input-box">
<input type="text" name="field[20]" id="field[20]" class="input-text" style="" value="">
</div>
</div>
#3: Now that my area to display, & variable are set up, we use jQuery to insert the variable into the actual value of the input-text form. I am doing this because within my CMS I am not able to simply add it in. I have to use jQuery to replace the text (which is empty box anyway).
$(".webforms-fields-enquiryfield .input-text").val('<?php echo htmlentities($_GET['product']); ?>');
Hope that made more sense.
I have figured the answer to this, the problem was that the CMS Magento likes to cache certain blocks - which is why I could view it first, then my CMS would store the variable but not erase it. No matter what kind of fixes I tried to disable caching, no go.
Instead I ended up using the following code, using a # variable, and some simple JavaScript that anyone can understand. I will be using this in future projects no doubt! Very easy variable passing ...
if(window.location.hash) {
var hash_value = window.location.hash.replace('#', '');
$("my-css-input-field-or-whatever-you-want").val(hash_value);
}
The hash_value can be used in a variety of ways now I suppose, and this works well around my Magento set up, it does not get cached/stored. Grabbing the URL location & hash instead.
(And the PHP used, simplified for anyone to replace/reuse within a CMS)
<a href="[GetBaseURLfromCMS]#[MyDynamicVariableHere] ">
I'm creating divs with dynamic names using php such as:
echo "<div class=\"".$row['country']."\">"
So it's going to first create a series of divs such as ...
<div class="America">
//stuff goes in here
</div>
<div class="Germany">
//stuff goes in here
</div>
<div class="Singapore">
//stuff goes in here
</div>
But later on in the code after the "Germany" div has already been created, I'm going to make another mysql query to a different table and I want to access the "Germany" class and add content in it. It then becomes something like...
<div class="Germany">
<p> Germany has x number of people </p>
<p> The most popular car in Germany is x </p>
</div>
I know with Jquery there is the append() function. Is there something similar in PHP where I can access a div that's already been created and add stuff to it?
Note: all of this is in one php file that loads all the content when the page loads.
It can be done. You can use output buffering to capture all output. Then you can use an HTML DOM parser to modify that output. After that, you can flush the lot.
But this will work only once and it will seriously slow down your script. Don't do it, it smells of bad design.
Your best option would be to create multiple variables like
$css['America'];
$css['Germany'];
$general_output;
etc and, while you are building your site, just add info to the required variable.
Once you get to the end of the page, print them in the right order and you are done.
I think you can create an array like
$div["Amereica"] = "America"
And in future you can append value to this array. eg.
$div["Amereica"] .= 'text to append';
And finally you can use implode function or using other array functions you can crate final html.
If you really need to re-access that element, you're probably looking for DOM functions or phpQuery
Simple answer is no.
You can't change HTML code produced by PHP, because that code is already sent to browser, and PHP works on server side.
One of complicated answers is #GolezTrol answer.
I have encountered something very, very weird. Working in VirtualBox, Ubuntu, Apache2, PHP, MySQL I got some very strange behaviour from one particular model.
I wanted to add ability to enter multiple language versions of the same string, say product name. I used jQuery to make nice tabs with languages and created temporary array to store all that information, used CActiveForm widget to collect and present data.
<?php foreach($languages as $language): ?>
<div id="tab_<?=$language->code?>">
<div class="row">
<?php echo $form->labelEx($model,'name'); ?>
<?php echo $form->textField($model,"translations[$language->code][name]",array('size'=>60,'maxlength'=>128)); ?>
<?php echo $form->error($model,"translations[$language->code][name]"); ?>
</div>
</div>
[...]
So this is how I collect data into a $translations array. This is my $translations array:
$translations = array(
'name' => 'NewName',
'sub_name' => 'Subname'
);
Then I obviously assign it to a proper model in Controler action:
[...]
foreach ($translations as $key => $value){
$x = new Translations();
$x->language = $key;
$x->id = $product->id;
$x->name = $value['name'];
$x->sub_name = $value['sub_name']
$x->save();
}
[...]
Now there are also other fields that are only one per product:
[...]
<div class="row">
<?php echo $form->labelEx($model,'something'); ?>
<?php echo $form->textField($model,'something',array('size'=>60,'maxlength'=>128)); ?>
<?php echo $form->error($model,"something"); ?>
</div>
</div>
And those are stored simply by
$product->save();
Everything is in a neat transaction.
HOWEVER....
What I get in result is like this (join on translations and product table):
id name subname something
1 NewN
2 NewName S
3 NewName Subname Som
4 NewName Subname Something
4 records when I only add ONE.... and more text I put in, more records are created. Split by random number of characters, sometimes as little as 4 sometimes as much as 12. This is repeatable but not always.... I am totaly dumbstruck by this behaviour.
Anyone ever saw anything like this and can shed ANY light on it?
Thanks in advance!
The problem could be coming in at many stages:
the form
the controller
binding the data from the form to the model
the model saving (ActiveRecord)
or even the database
So 'divide and conquer' your problem.
MySQL
Turn on your 'general mysql log' to see the queries that are being sent to MySQL. If they look like the weird forms you are seeing above, then it's not the database. It's unlikely you'll have any problems at this stage, but it's good to rule it out.
ActiveRecord
Then hardcode your values into the model. In your controller, just create an instance of the model and save it. Does that replicate the problem you're having? If so, it's a problem with your implementation of ActiveRecord. Try removing the relationships and work on that.
Controller
There could be something weird in your controller. Again, hardcode the data that you want to pass to the model when you create the instance.
Binding
It could be a problem with how you are binding data from the form to the model. Manually set the values of the form, then bind that data to the model as normal.
This is where back-end testing can really help you, as you can isolate what's working from what's not. Look into tools like Behat and PHPUnit.
I've built an online community in Drupal with a homepage that is kind of like the Facebook wall. You see the 25 most recent posts, with the two most recent comments below those posts. There is also a textarea right below those comments so that you can quickly post a new comment on a particular post.
These Facebook-style posts have a lot of functionality built into them via JavaScript. Clicking a "view all comments" link directly below a post makes an AJAX call that grabs all the comments for that post and displays them right below it. You can also mark posts as helpful, as the solution to your question, edit comments inline, etc. All of these actions require AJAX requests, which means that the JavaScript making the request needs to know essential information such as the Node ID (the unique identifier of the post), the comment ID (unique identifier of the comment), etc.
My initial implementation had these pieces of essential data sprinkled all over the posts, making it more complicated to write the JS that needed to find it. So my second implementation simply output all this data into a JSON-compatible string in the main wrapping element of each post. While this made it much easier for the JS to find the data it needed, writing JSON as a string is a pain (escaping quotes, no line breaks).
So now I have a third idea, and I'm looking for feedback on it prior to implementation. The idea is to create a single global JS Array for all these posts that contains within it objects that hold the data for each post. Each element in that array would hold the necessary data needed for the AJAX calls. So it would look something like this:
Facebook-style post template
<div class="post" data-postindex="<?php echo $post->index; ?>">
<!-- lots of other HTML for the post -->
</div>
<script type="text/javascript">
globalPostArray.push({
nid: <?php echo $post->nid; ?>,
authorID: <?php $post->authorID; ?>,
//etc. etc. etc.
});
</script>
The result of the above code is that when a link gets clicked that requires an AJAX request, the JS would simply traverse the DOM upwards from that link until it finds the main .post element. It would then grab the value of data-postindex in order to know which element in globalPostArray holds the data it needs.
Thoughts? I feel like there must be some standard, accepted way of accomplishing something like this.
I've never heard of a standard way to "pass" information between PHP and Javascript, as they are a server-side and client-side language, respectively. I would personally use a hybrid of your second and third solutions.
Store the post id in a data-postindex attribute (data attributes are newish, and the "right" way to store small amounts of data). But I would still just use a JSON array for the rest, as storing lots of data in data-attributes (and escaping them!) is potentially problematic. PHP has a json_encode function that takes care of all the escaping and such for you - just build a PHP array (say, $postdata) like you normally would, and then throw this in your post template:
<script type="text/javascript">
globalPostArray.push(<?php echo json_encode($postdata) ?>);
</script>
Where $postdata is something like the following:
$postdata = array(
'nid' => 5,
'authorId' => 45
...etc...
);
It should be easy enough to generate such an array from your existing code.
I wrote a blog post a while back about my implementation of this kind of thing, but it sounds like all you need is a pointer at json_encode.
The most reliable way to pass any PHP variable to JavaScript is json_encode.
<script type="text/javascript">
var something = <?php echo json_encode($var); ?>;
</script>
You can't pass closures and resources, but otherwise anything's game for being passed.
I would store the data inside the element:
<div class="post" data-postindex="<?php echo $post->index; ?>"
data-nid="<?php echo $post->nid; ?>"
data-authorID="<?php echo $post->authorID; ?>">
...or storing a complete JSON-string in 1 data-attribute:
<div data-data="<?php echo htmlentities(json_encode($somedata));?>">
My answer is about the same as the other guys but more detailed. I usually do it like this and i think is the best approach: (of course you can grab the data using ajax, but depends on the context)
somefile.html
<html>
<head>..</head>
<body>
html code
<script>
window.my_data = <?php echo json_encode($my_php_var); ?>
</script>
</body>
</html>
somefile.js
$(function() {
window.myitem = new myClass(window.my_data);
});
var MyClass = function(init_data) {...}