Yeoman: can you call a method from within a template? - yeoman

Can you call a method from within a Yeoman template, in place of where a templateData property is normally injected?
I'm looking to generate a random guid multiple times within a template. In my _Product.xml template file I have:-
<someNode value="<%= randomGuid %>">
<someNode value="<%= randomGuid %>">
<someNode value="<%= randomGuid %>">
<someNode value="<%= randomGuid %>">
<someNode value="<%= randomGuid %>">
Then in my yeoman generator I have:-
_buildTemplateData() {
this.templatedata.randomGuid = uuid.v4();
}
writeToDisk() {
this.fs.copyTpl(this.templatePath('_Product.xml'), this.destinationPath('Product.xml'), this.templatedata);
}
And I was hoping to get:-
<someNode value="43EE86E4-AC19-4A82-A053-7FE0857AB1F5"/>
<someNode value="7F7184CF-23A7-4383-B5BB-E3A383BC6A0A"/>
<someNode value="5B7A26C1-A449-4B35-94E3-D214C62CEAD7"/>
<someNode value="641D7EC0-AFB1-4646-8B52-5DC71B8FFC50"/>
<someNode value="CEB94BA1-D487-4838-A354-FAFB4D8B188A"/>
but instead I get:-
<someNode value="43EE86E4-AC19-4A82-A053-7FE0857AB1F5"/>
<someNode value="43EE86E4-AC19-4A82-A053-7FE0857AB1F5"/>
<someNode value="43EE86E4-AC19-4A82-A053-7FE0857AB1F5"/>
<someNode value="43EE86E4-AC19-4A82-A053-7FE0857AB1F5"/>
<someNode value="43EE86E4-AC19-4A82-A053-7FE0857AB1F5"/>
I know I could create a bunch of Guids as properties of templateData, and pass them all in, referencing each one individually, but I'd like to avoid that as I have no need to reuse the guid outside of the Product.xml file, and I'd like to trim down the code as much as possible.
I'm also looking to do something similar with a function call....but this is the more basic example to post here.
Any ideas?
Thanks

Yes, it's possible. Pass a function as template context:
this.fs.copyTpl(a, b, {
getUuid: () => uuid.v4()
});
Then call it in your template:
<someNode value="<%= getUuid() %>">

Related

How to dynamically generate a PayPal button with Rails?

I have an e-commerce website with many different products with different prices, and I want to allow people to buy them using PayPal. This guide details how to create a PayPal Buy Now button, but you have to manually fill out a form. This would be very very time consuming to do every time I add a product.
I looked at the HTML of the Buy Now button, hoping to be able to inject my product information with ERB, but nowhere in the HTML is the product information like price listed. Instead, there's a very long "value" element, and I assume the product information is encrypted within this.
Anyone know how to dynamically generate a PayPal button with Rails? If not, does anyone know of am alternative I could use?
You can inject the data as below:
ERB sample (in case you are sending one product):
<li>
<b>product name:</b> <%= #product.name %>
<br>
<b>product price:</b> <%= #product.price %>
<b style='text-decoration: underline;'>Pay:</b>
<form target="paypal" action="https://www.paypal.com/cgi-bin/webscr" method="post" >
<input type="hidden" name="cmd" value="_cart">
<input type="hidden" name="business" value="yourbusinessmail#hotmail.com*">
<input type="hidden" name="lc" value="US">
<input type="hidden" name="item_name" value="<%= #product.name %>">
<input type="hidden" name="item_number" value="<%= #product.id %>">
<input type="hidden" name="amount" value="<%= #product.price %>">
<input type="hidden" name="currency_code" value="USD">
<input type="hidden" name="button_subtype" value="products">
<input type="hidden" name="no_note" value="0">
<input type="hidden" name="shipping" value="<%= #product.shipping %>">
<input type="hidden" name="add" value="1">
<input type="hidden" name="bn" value="PP-ShopCartBF:btn_cart_LG.gif:NonHostedGuest">
<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_cart_LG.gif" border="0" name="submit" >
<img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1">
</form>
</li>
Use below Paypal website link to customize your button then you can inject values as in Ruby code:
Design Paypal button

i want to get the form data form one gsp and want to access that data in another gsp and want to insert that data in table, how can i do this?

This is one gsp where i created one form
<div class="form-group">
<label for="msg_to">To</label>
<input type="email" id="msg_to" name="msg_to" class="form-control" style="width:500px;" required="">
</div>
<div class="form-group">
<label for="msg_subject">Subject</label>
<input type="text" id="msg_subject" class="form-control" style="width:500px;"name="msg_subject" required="" maxlength="50">
</div>
<div class="form-group">
<label for="msg_body">Body</label>
<textarea class="form-control" id="msg_body" style="width: 500px; height: 250px" name="msg_body" required="" ></textarea>
</div>
%{--<button type="submit" class="btn btn-default">Send</button>--}%
<g:actionSubmit value="Send" action="g_Inbox" style="color: #000000"></g:actionSubmit>
</form>
The data of above form must be access to another controller after submit and data should be display in the table form on that another view.
I fetch above data in following action:
def g_Inbox(){
def msg_to = params.msg_to;
def msg_subject = params.msg_subject;
def msg_body = params.msg_body;
println msg_to
println msg_subject
println msg_body
render(view: 'g_Inbox', model: [m_to : msg_to , m_sub : msg_subject , m_body: msg_body] )
}
from here i want to send it to view and want to add in new row of table..
You're in luck. What you want to do is very easy with Grails. But... you have to do your homework.
Things to read and digest
(best served with pizza and iced tea)
Groovy Server Pages -
https://grails.github.io/grails-doc/latest/guide/theWebLayer.html#gsp
Controllers - https://grails.github.io/grails-doc/latest/guide/theWebLayer.html#controllers
Once you understand GSP and controllers, you'll know exactly what to do.
Simple if You know how it works
render(view: 'g_Inbox', model:[params:params])
Access the params in gsp by
${params.msg_to}
and for Another Controller
redirect controller:'Controller' action: 'create',params:params

Challenge with merging two params

I have following entry in my routes for subcategory**(a.k.a. type)** pages:
match '/jewellery/:taxon/(:tag)' => 'shop#index', :as => 'shop'
I also have a set of filters (type, material, plating etc) on the subcategory pages. So, consider a taxon "Earrings". I have following subcategories in this taxon - "Danglers", "Hoops", "Studs".
So, the corresponding subcategory pages are "/jewellery/earrings/danglers", "/jewellery/earrings/hoops" and "/jewellery/earrings/studs".
I want a functionality that if a user goes to sub-category page, the corresponding checkbox in the type filter should be checked. So, if I go to "/jewellery/earrings/studs" the checkbox labelled "Studs" should be checked by default. I want to allow multiple type selection, so input from filters needs to be an array. I have the following code:
<% Typelabels.each { |label| %>
<%if filter[:name] == "Type"%>
<% if (!params["type"].nil? && (params["type"].member? label))
or (!params[:tag].nil? && params[:tag].gsub(/[+-]/," ") == label.downcase)%>
<input type="checkbox" id='<%= label.to_s %>' name="type[]" value="<%= label %>" checked />
<label for="<%= label.to_s %>" class="<%= t %>_name_label"><%= label%></label>
<%else%>
<input type="checkbox" id='<%= label.to_s %>' name="type[]" value="<%= label %>"/>
<label for="<%= label.to_s %>" class="<%= t %>_name_label"><%= label%></label>
<%end%>
<% end %>
<%}%>
But challenge is that when I un-check the box "Studs" (which was checked by default, on "/jewellery/earrings/studs"), I get redirected to the same page as the tag in params is fixed.
Please can someone help me

How to compare AngularJS value to ruby on rails variable value

I am using Firebase in a pretty simple chat application. One of the features i'm working on now is the ability to update messages in the chat room, but only if you were the original author. For the editing i have an icon that, when clicked, will do some javascript to hide the message div and display a previously hidden div that has the update form in it. But i only want this to be available if you were the author of the message. Here's what the code looks like:
<li class="message phm pvm pull-left" ng-repeat="(msgId,msg) in room.messages">
<div class="message-current" data-message-id="{{msgId}}">
<span class="message-author pull-left">{{msg.author}}</span>
<span class="message-body pull-left pls">{{msg.body}}</span>
<span class="message-timestamp pull-right prs">
{{msg.timestamp | date:'MMM d, yyyy h:mm a'}}
<a class="message-update-link" href="#" ng-click="showMessageUpdate(msgId)"><span class="glyphicon glyphicon-pencil"></span></a>
</span>
</div>
<div class="message-update hidden" data-message-id="{{msgId}}">
<form class="form-inline" ng-submit="updateMessage(roomId, msgId, '<%= current_user.full_name %>')">
<textarea class="form-control update-message" ng-model="msg.body" ng-trim="false">{{msg.body}}</textarea>
<input class="button button-large button-primary" type="submit" value="Update">
</form>
</div>
</li>
Right now, i can only get it to have updatable message for ALL message or no messages. Basically, the part i am stuck on is the check of whether or not the angularjs value of {{msg.author}} is equal to the rails value of <%= current_user.id %>. Any thoughts on how this can be achieved? Thanks for any help!
SOLVED:
Thanks to Jiten for the step in the right direction. I'm new to learning AngularJS and it's pretty complex. Sometimes you just need to know where to start.
I ended up using a combination of the ngIf directive and the angular.equals function. In my rails view i used ng-if="isAuthor(msg.author, '<%= current_user.full_name %>')" on anything i wanted available to authors of that message only. This will evaluate the response of isAuthor() and only render to the dom if it evaluates to true. The code above now looks like this:
<li class="message phm pvm pull-left" ng-repeat="(msgId,msg) in room.messages">
<div class="message-current" data-message-id="{{msgId}}">
<span class="message-author pull-left">{{msg.author}}</span>
<span class="message-body pull-left pls">{{msg.body}}</span>
<span class="message-timestamp pull-right prs">
{{msg.timestamp | date:'MMM d, yyyy h:mm a'}}
<a ng-if="isAuthor(msg.author, '<%= current_user.full_name %>')" class="message-update-link" href="#" ng-click="showMessageUpdate(msgId)"><span class="glyphicon glyphicon-pencil"></span></a>
</span>
</div>
<div ng-if="isAuthor(msg.author, '<%= current_user.full_name %>')" class="message-update hidden" data-message-id="{{msgId}}">
<form class="form-inline" ng-submit="updateMessage(roomId, msgId, '<%= current_user.full_name %>')">
<textarea class="form-control update-message" ng-model="msg.body" ng-trim="false">{{msg.body}}</textarea>
<input class="button button-large button-primary" type="submit" value="Update">
</form>
</div>
</li>
Here is what isAuthor() looks like in my AngularJS controller:
$scope.isAuthor = function(msgAuthor, currentUser) {
return angular.equals(msgAuthor, currentUser);
}
Pretty simple really!
To compare two objects you can use:
angular.equals({{msg.authorId}}, <%= current_user.full_name %>)

Rails select with multiple options only sends one

I have this form :
<form accept-charset="UTF-8" action="/contracts/<%= params[:id] %>/addConsultants" method="POST" id="updateConsultants"><!---->
<div style="margin:0;padding:0;display:inline">
<input name="utf8" type="hidden" value="✓">
<input name="authenticity_token" type="hidden" value="<%= session[:_csrf_token] %>">
</div>
<div class="consultant_selector">
<h2>Consultants</h2>
<select name="consultants_available" size="10" multiple>
<% #users.each do |u| %>
<option value="<%= u[:id_user] %>"><%= u[:name] %></option>
<% end %>
</select>
<ul>
<li class="triangle_right" id="add_consultant"></li>
<li class="triangle_left" id="remove_consultant"></li>
</ul>
<select name="consultants_selected" size="10" multiple>
</select>
</div>
<div>
<input type="submit" value="Mettre à jour" />
</div>
</form>
And in my controller :
def add_consultants
#contract = Contract.find(params[:id])
#consultants = params[:consultants_selected];
puts "------ Consultants: #{#consultants}"
redirect_to contract_path
end
The idea is that I can select names from the first select, move them to the second by clicking on the triangle and then submit the form to assign these names to a contract. However, when I do this the call to puts only prints one ID out of the 3 I have in the second select (all three of them have the selected attribute to true). How do I get multiple values?
Just found the answer here : https://stackoverflow.com/a/2196522/1796742
Changing the name of the second select from:
<select name="consultants_selected" size="10" multiple>
</select>
To :
<select name="consultants_selected[]" size="10" multiple>
</select>
Worked.

Resources