How to use variable in phoenix framework in a handle_event function? - templates

I would like to have two input fields in two different forms (see below). The first one submits the user's name and saves it in variable client_name. This seems to work fine.
When the second one is submitted, I would like to grab hold of the client_name variable and use it in the string I create. But I don't know how.
defmodule ChatWeb.ChatLive do
use ChatWeb, :live_view
#topic "message_received"
def mount(params, session, socket) do
ChatWeb.Endpoint.subscribe(#topic)
{:ok, assign(socket, :text_value, "") |>assign(:client_name, "")}
end
def render(assigns) do
~H"""
<h1>Chat</h1>
<form phx-submit="submit_name">
<label>Your name: <%= #client_name %><input id="client" type="text" name="client" /></label>
<input type="submit" />
</form>
<form phx-submit="submit">
<label>Your Text:<input id="msg" type="text" name="input_value" /></label>
<input type="submit" />
</form>
<div id="chat">
Chat history: <%= #text_value %>
</div>
"""
end
def handle_event("submit_name", %{"client" => client}, socket) do
{:noreply, assign(socket, :client_name, client)}
end
def handle_event("submit", %{"input_value" => msg}, socket) do
ChatWeb.Endpoint.broadcast_from(self(), #topic, "message_received_received", "| Message by #{client_name}: '" <> msg <> "' ")
{:noreply, assign(socket, :text_value, "| Message by #{client_name}: '" <> msg <> "' " <> socket.assigns.text_value)}
end
def handle_info(%{topic: #topic, payload: new_message}, socket ) do
{:noreply, assign(socket, :text_value, new_message <> socket.assigns.text_value)}
end
end
The Problem is with the #{client_name}
What would be the correct notation?
My error says: undefined function client_name/0

Your call to client_name should be changed to socket.assigns.client_name as this is where you put the value in the handle_event("submit_name", ...).
Alternatively you can bind the client_name assign in the function clause:
def handle_event("submit", %{"input_value" => msg}, %{assigns: %{client_name: client_name}} = socket) do
In this case you don't need to fix client_name in the function body.

Related

How can I do both email control and custom domain control with regex?

I want to check text which entered form field. Text must be valid email and shouldn't contain specific domain between "#" and "." sign. How can I do this with using regex? For example I want an email that shouldn't contain "test" domain
mail#mail => Invalid
mail#test.com => Invalid (Because contain 'test' domain)
mail#mail.com => Valid
HTML
<form>
<input type="text" id="email">
<button type="submit" id="sendMail">Send</button>
</form>
I can handle valid email with following pattern:
JS
const btn = document.getElementById('sendMail');
btn.addEventListener('click', (e) => {
e.preventDefault();
const emailPtrn = /^(([^<>()\[\]\\.,;:\s#"]+(\.[^<>()\[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
const email = document.getElementById('email');
alert(emailPtrn.test(email.value));
});
JSfiddle Link
How can I check this with single pattern?
Just add (?!test\.) negative look ahead after # in your current regex,
^(([^<>()\[\]\\.,;:\s#"]+(\.[^<>()\[\]\\.,;:\s#"]+)*)|(".+"))#(?!test\.)((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$
^^^^^^^^^^ This will reject any email if what follows immediately after # is test.
Regex Demo

AMAZON: Add to remote cart without leaving site

Hey I'm trying to set up a remote cart. Very frustrating though since Amazon doesn't list any code examples for a remote cart without the customer leaving the site.
Here's where I'm at so far. I can get someone to leave my site and add the product from my site to Amazon using this (From: http://docs.aws.amazon.com/AWSECommerceService/latest/DG/AddToCartForm.html):
<form method="GET" action="http://www.amazon.com/gp/aws/cart/add.html">
<input type="hidden" name="AWSAccessKeyId" value="Access Key ID" /> <br/>
<input type="hidden" name="AssociateTag" value="Associate Tag" /><br/>
<p>One Product<br/>
ASIN:<input type="text" name="ASIN.1"/><br/>
Quantity:<input type="text" name="Quantity.1"/><br/>
<p>Another Product<br/>
ASIN:<input type="text" name="ASIN.2"/><br/>
Quantity:<input type="text" name="Quantity.2"/><br/>
</p>
<input type="submit" name="add" value="add" />
</form>
But I want to make it so they can add an item to cart and stay on my site. It seems like this is how I accomplish that:
http://webservices.amazon.com/onca/xml?
Service=AWSECommerceService&
AWSAccessKeyId=[AWS Access Key ID]&
AssociateTag=[Associate Tag]&
Operation=CartCreate&
Item.1.OfferListingId=B000062TU1&
Item.1.Quantity=2
&Timestamp=[YYYY-MM-DDThh:mm:ssZ]
&Signature=[Request Signature]
But when I'm totally confused as to how to generate a timestamp and signature. Do I put this into a form action? Is there anywhere with code examples? I've been searching all day and can't find it. Any help greatly appreciated.
I'm using this method to generate api request url, and its totally working fine. Believe this will help you
$uri = "/onca/xml";
$asin = "B00C5AHTC0";
$end_point = "webservices.amazon.com";
$params = array(
"Service" => "AWSECommerceService",
"Operation" => "CartCreate",
'Version' => "2013-08-01",
"AWSAccessKeyId" => AWS_ACCESS_KEY,
"AssociateTag" => AWS_ASSOCIATE_TAG,
"Item.1.ASIN" => $asin,
"Item.1.Quantity" => "5",
"Timestamp"=> gmdate('Y-m-d\TH:i:s\Z')
);
// Sort the parameters by key
ksort($params);
$pairs = array();
foreach ($params as $key => $value) {
array_push($pairs, rawurlencode($key) . "=" . rawurlencode($value));
}
// Generate the canonical query
$canonical_query_string = join("&", $pairs);
$string_to_sign = "GET\n" . $end_point. "\n" . $uri . "\n" . $canonical_query_string;
$signature = base64_encode(hash_hmac("sha256", $string_to_sign, AWS_SECRET_KEY, true));
$request_url = 'http://' . $end_point. $uri . '?' .$canonical_query_string . '&Signature='.rawurlencode($signature);

Regex test works but breaks when it's passed to HTML5 input pattern attribute

I'm trying to use this pattern on a password field that says "Password should be min 6 chars and contain 1 non-alphabet character":
^(?=.{6})(?=.*[^a-zA-Z])
However when passing this into the pattern attribute it stops working. Check this demo:
document.querySelector('form').addEventListener("submit", onFormSubmit);
function onFormSubmit(e) {
e.preventDefault();
var pwEl = document.querySelector('.password');
alert('With pattern: ' + pwEl.checkValidity() + ', without pattern: ' + /^(?=.{6})(?=.*[^a-zA-Z])/.test(pwEl.value));
}
<form novalidate>
<input class="password" type="password" placeholder="Enter password" pattern="^(?=.{6})(?=.*[^a-zA-Z])" />
<button type="submit">submit</button>
</form>
Try entering:
"password" both are false
"password1" pattern is false but regex with the same pattern works

Why is this erb code throwing "Undefined method 'match' for []:Array"?

Hope someone can help me resolve this problem.
I have an instance variable holding some string values in a params. Here are the string values:
"The Hoboken Four" "Anita Baker" "No One Cares" "Giant" "Taking A Chance On Love" "[]" "["quiz"]" "quiz"
I would like to display only the values that match:
"The Hoboken Four" "Anita Baker" "No One Cares" "Giant" "Taking A Chance On Love"
Here is the code in my app.rb:
post '/:form_type' do
#array = []
#results = params
#results.each do |key, value|
if value.match(/\w[^["quiz"]]/)
#array << value
end
#array
end
erb :results
end
Here is the code I have in my view:
<% #array.each do |item| %>
<p><%= item %></p>
<% end %>
Thank you for helping!
Just for the record, what I think happened is that OP was using [] in the parameters name, most likely to send all the values under a unique name. For instance if the HTML form looks like that:
<input type="text" name="title[]"/>
<input type="text" name="title[]"/>
and the user inputs First and Second, Sinatra is going to interpret the [] in the parameter name and aggregate the different values in a table:
{"title"=>["First", "Second"]}
So in OP's code, value.match was throwing because value was of type Array (as the error message states).

No need of CGI.script_name

Please refer to the following code:
<cfform method="POST" action="#CGI.script_name#">
<p>Enter your Name:
<input name="name" type="text" hspace="30" maxlength="30">
<input type="Submit" name="submit" value="OK">
</cfform>
<cfscript>
function HelloFriend(Name) {
if (Name is "") WriteOutput("You forgot your name!");
else WriteOutput("Hello " & name &"!");
return "";
}
if (IsDefined("Form.submit")) HelloFriend(Form.name);
</cfscript>
Source: http://livedocs.adobe.com/coldfusion/8/htmldocs/help.html?content=UDFs_01.html#1167055
The code runs fine even without CGI.script_name attribute of action field. May I know why it's required then? The description says "Uses the script_name CGI variable to post to this page without specifying a URL. "
The default action of an HTML form is to submit to itself when no action is specified. See this related discussion on the topic: Is it a good practice to use an empty URL for a HTML form's action attribute? (action="")
I always include an action, if for no other reason, to avoid confusion.