How to translate text generated with javascript - javascript

So adminlte has the trans() function which works perfectly when its used in blade.php.
Lets say i have a form that if completed incorrectly throws a warning. I do the checking in js. And I want to have a pop up message that is displayed. The message need to be translatable.
What I tried is - in the php file make an array with the translatable text:
$returnArr = [
'titleSuccess' => trans('title.success'),
'titleWarning' => trans('title.warning')
];
Then retrieve it in the js and display the message.
$.post('/' + currentLanguage.locale + '/admin/page/error', {id:sId, note:note})
.done(function (result) {
if (result.status === 1) {
msg
.html(createAlert(result.titleSuccess, result.msg, 'success'))
.slideDown('fast');
} else {
msg
.html(createAlert(result.titleError, result.msg, 'danger'))
.slideDown('fast');
}
})
The problem is these keywords- title.warning, title.success are translated but in the default language that is set in the system. Not the one that the user has set.
Why is that happening? And is there a way to use trans() in js?

Related

SOLVED: JQuery reading EJS variable as a String and not the value of the EJS request

Alright, so I'm having a bit of a problem. I have an app that displays some facts via a search input. If that fact isn't existing, I want to display an error.
I'm producing that error via Node on the backend, and via EJS sends the error message to the HTML (.ejs) and javascript files.
Long story short, the error message displays correctly, but the error popup also displays when refreshing the page, even though there isn't any errors to display.
Error.js
var clientError = "<%=clientError%>"; //<--- (1) see comment below
$("#error").hide();
if(clientError !== "") { //<--- (2) see comment below
$("#error").fadeIn().show();
setTimeout(function(){
$("#error").fadeOut().hide();
}, 4000);
}
(1) This is being interpreted as the word "clientError" and characters "<%=%>" of "<%=clientError%>", and NOT the value of the .ejs query, for example, "An error occurred". This leads to problem no. 2, see below.
(2) Because "<%=clientError%>" isn't being read as an empty string, even if there aren't any errormessages, it runs the code either way and displays the error-popup. So when I refresh the website I get the popup, because the string isn't empty (even though it doesn't display any message, because there aren't any errors).
I have also tried some other variants of the error.js code, for example:
if(clientError.length >= 17) ...executes error popup // no luck with this either, see comment 1 and 2 above.
//I have also tried not defining clientError in App.js:
var clientError;
//And then inside error.js:
if(clientError !== undefined) ...executes error popup //no luck with this, since error.js reads it as a defined string.
App.js
var clientError = ""; //<-- (3)
...
...
app.get("/:option/:input", function(req, res) {
var opt = req.params.option;
var inp = req.params.input;
Article.find({
option: lodash.capitalize(opt),
input: lodash.capitalize(inp)
}, function(err, foundArticle) {
if (err) {
clientError = "Internal Server Error. Contact Administrator.";
setTimeout(function(){
clientError = "";
},4000);
console.log(err);
}
else if ((!foundArticle) || (foundArticle.length <= 0)) {
const notFound = new Notfound({
option: searchOptions,
input: searchInput
});
clientError = "Article not found. Try again."
setTimeout(function(){
clientError = "";
},4000);
res.redirect("/");
} else {
Article.findById(someIdOrSomething, function(err, someArticle){
res.render("page", {
...
clientError: clientError,
});
});
}
});
})
(3) An empty string. So the string in error.js should be read as an empty string, shouldn't it?
At last, we have the error.EJS
error.ejs
<div id="error" class="error-popup">
<h4>An error occurred.</h4>
<p id="errormessage"><%=clientError%></p>
</div>
One idea might be to have an input instead of the paragraph element above that's disabled as such...
<input id="errormessage" disabled type="text" value="<%=clientError%>">
... and then use Jquery to get the value of the input.
EDIT:
The idea above worked! Here is the new code:
error.js
$("#error").addClass("error-popup");
if($("#errormessage").val() !== "") {
$("#error").fadeIn().addClass("show-error-popup");
setTimeout(function(){
$("#error").fadeOut().removeClass("show-error-popup");
}, 4000);
}
error.ejs
<div id="error" class="error-popup">
<h4>An error occurred</h4>
<input id="errormessage" disabled type="text" value="<%=clientError%>">
</div>
Next step is just to style the input so it doesn't look like a regular input.

selenium cucumber javascript use faker to fill different value on iteration

I am new on automation selenium using javascript, I have simple code like below that I am using faker data to generate random email, question is incase I have data table on scenario outline 2 types, when I run the code some how the data for email for second loop is using same data that generated on first loop, question is how to get different data for 2nd loop?
#feature file
#RegisterMerchant
Feature: Register new merchant
Scenario Outline: As a new User, I want to create new merchant account
Given User is on register page
When User fill register form for "<businessChannel>" merchant
And User click register
Then User should see success pop up message
Examples:
| businessChannel |
| offline |
| online |
#data file
const faker = require('faker')
class registerData {
email = faker.name.firstName().toLowerCase() + faker.name.lastName().toLowerCase() + "#mailinator.com"
}
module.exports = new registerData()
#step file
const { Given, When, Then } = require('cucumber');
const registerPage = require('../PageObjects/registerMerchantPage')
Given(/^User is on register page$/, () => {
registerPage.isOnRegisterPage()
});
When(/^User fill register form for "([^"]*)" merchant$/, (businessChannel) => {
registerPage.inputRegisterForm(businessChannel) ..
});
When(/^User click register$/, () => {
registerPage.signUpButton.click()
});
Then(/^User should see success pop up message$/, () => {
registerPage.showPopUpSuccess()
});
Actual the 2nd iteration still using 1st faker data
#page object file
inputRegisterForm(businessChannel) {
this.emailAddressField.addValue(registerData.email)
switch (businessChannel) {
case "online":
this.onlineRadBtn.click()
break;
case "offline":
this.offlineRadBtn.click()
break;
}
}
solved by add function for this data file :
email = faker.name.firstName().toLowerCase() + faker.name.lastName().toLowerCase() + "#mailinator.com"
to be like this
#data file
class registerData {
generateRegisterData() {
this.email = faker.name.firstName().toLowerCase() + faker.name.lastName().toLowerCase() + "#mailinator.com"
console.log("Test")
}
email = ""
#page object file
inputRegisterForm(businessChannel) {
registerData.generateRegisterData()
this.emailAddressField.addValue(registerData.email)
switch (businessChannel) {
case "online":
this.onlineRadBtn.click()
break;
case "offline":
this.offlineRadBtn.click()
break;
}
}

How do I populate a list field in a model from javascript?

I have a Kendo.MVC project. The view has a model with a field of type List<>. I want to populate the List from a Javascript function. I've tried several ways, but can't get it working. Can someone explain what I'm doing wrong?
So here is my model:
public class Dashboard
{
public List<Note> ListNotes { get; set; }
}
I use the ListNotes on the view like this:
foreach (Note note in Model.ListNotes)
{
#Html.Raw(note.NoteText)
}
This works if I populate Model.ListNotes in the controller when the view starts...
public ActionResult DashBoard(string xsr, string vst)
{
var notes = rep.GetNotesByCompanyID(user.ResID, 7, 7);
List<Koorsen.Models.Note> listNotes = new List<Koorsen.Models.Note>();
Dashboard employee = new Dashboard
{
ResID = intUser,
Type = intType,
FirstName = user.FirstName,
LastName = user.LastName,
ListNotes = listNotes
};
return View(employee);
}
... but I need to populate ListNotes in a Javascript after a user action.
Here is my javascript to make an ajax call to populate ListNotes:
function getReminders(e)
{
var userID = '#ViewBag.CurrUser';
$.ajax({
url: "/api/WoApi/GetReminders/" + userID,
dataType: "json",
type: "GET",
success: function (notes)
{
// Need to assign notes to Model.ListNotes here
}
});
}
Here's the method it calls with the ajax call. I've confirmed ListNotes does have the values I want; it is not empty.
public List<Koorsen.Models.Note> GetReminders(int id)
{
var notes = rep.GetNotesByCompanyID(id, 7, 7);
List<Koorsen.Models.Note> listNotes = new List<Koorsen.Models.Note>();
foreach (Koorsen.OpenAccess.Note note in notes)
{
Koorsen.Models.Note newNote = new Koorsen.Models.Note()
{
NoteID = note.NoteID,
CompanyID = note.CompanyID,
LocationID = note.LocationID,
NoteText = note.NoteText,
NoteType = note.NoteType,
InternalNote = note.InternalNote,
NoteDate = note.NoteDate,
Active = note.Active,
AddBy = note.AddBy,
AddDate = note.AddDate,
ModBy = note.ModBy,
ModDate = note.ModDate
};
listNotes.Add(newNote);
}
return listNotes;
}
If ListNotes was a string, I would have added a hidden field and populated it in Javascript. But that didn't work for ListNotes. I didn't get an error, but the text on the screen didn't change.
#Html.HiddenFor(x => x.ListNotes)
...
...
$("#ListNotes").val(notes);
I also tried
#Model.ListNotes = notes; // This threw an unterminated template literal error
document.getElementById('ListNotes').value = notes;
I've even tried refreshing the page after assigning the value:
window.location.reload();
and refreshing the panel bar the code is in
var panelBar = $("#IntroPanelBar").data("kendoPanelBar");
panelBar.reload();
Can someone explain how to get this to work?
I don't know if this will cloud the issue, but the reason I need to populate the model in javascript with an ajax call is because Model.ListNotes is being used in a Kendo Panel Bar control and I don't want Model.ListNotes to have a value until the user expands the panel bar.
Here's the code for the panel bar:
#{
#(Html.Kendo().PanelBar().Name("IntroPanelBar")
.Items(items =>
{
items
.Add()
.Text("View Important Notes and Messages")
.Expanded(false)
.Content(
#<text>
#RenderReminders()
</text>
);
}
)
.Events(e => e
.Expand("getReminders")
)
)
}
Here's the helper than renders the contents:
#helper RenderReminders()
{
if (Model.ListNotes.Count <= 0)
{
#Html.Raw("No Current Messages");
}
else
{
foreach (Note note in Model.ListNotes)
{
#Html.Raw(note.NoteText)
<br />
}
}
}
The panel bar and the helpers work fine if I populate Model.ListNotes in the controller and pass Model to the view. I just can't get it to populate in the javascript after the user expands the panel bar.
Perhaps this will do it for you. I will provide a small working example I believe you can easily extend to meet your needs. I would recommend writing the html by hand instead of using the helper methods such as #html.raw since #html.raw is just a tool to generate html in the end anyways. You can write html manually accomplish what the helper methods do anyway and I think it will be easier for you in this situation. If you write the html correctly it should bind to the model correctly (which means it won't be empty on your post request model) So if you modify that html using javascript correctly, it will bind to your model correctly as well.
Take a look at some of these examples to get a better idea of what I am talking about:
http://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx
http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/
So to answer your question...
You could build a hidden container to hold your list values like this (make sure this container is inside the form):
<div id="ListValues" style="display:none">
</div>
Then put the results your ajax post into a javascript variable (not shown).
Then in javascript do something like this:
$('form').off('submit'); //i do this to prevent duplicate bindings depending on how this page may be rendered futuristically as a safety precaution.
$('form').on('submit', function (e) { //on submit, modify the form data to include the information you want inside of your ListNotes
var data = getAjaxResults(); //data represents your ajax results. You can acquire and format that how you'd like I will use the following as an example format for how you could save the results as JSON data: [{NoteID ="1",CompanyID ="2"}]
let listLength = data.length;
for (let i = 0; i < listLength; i++) {
$('#ListValues').append('<input type="text" name="ListNotes['+i+'].NoteID " value="' + data.NoteID +'" />')
$('#ListValues').append('<input type="text" name="ListNotes['+i+'].CompanyID " value="' + data.CompanyID +'" />')
//for your ajax results, do this for each field on the note object
}
})
That should do it! After you submit your form, it should automatically model bind to you ListNotes! You will be able to inpsect this in your debugger on your post controller action.

Show callback after button click

This is pretty a newby question but I can't figure this one out because it is a different approach/way of writing then I'm used to!
I'm using the app "Back in Stock" for a webshop that's not shopify but something like that. This app shows a modal when a product is out of stock to register your email to recieve an update.
Further I created my own modal because of translation issues and more country related stuff.
I'm having trouble to create or to run a function to show a success or error message when I click a button.
The docs say that this is the way to grab all messages:
var notificationCallback = function(data) {
var msg = '';
if (data.status == 'OK') {
msg = data.message; // just show the success message
} else { // it was an error
for (var k in data.errors) { // collect all the error messages into a string
msg += data.errors[k].join();
}
}
alert(msg);
}
I have created a function that shows the popup and handles the submit:
<button class="notify_button pp pull-right" data-product-id="{{ product.id }}" data-variant-id="{{ product.vid }}" onclick="notify_me_function(this,event);">{{ 'Email when available' | t }}</button>
function notify_me_function(el ,event){
var variantId = $(el).data('variant-id');
var productId = $(el).data('product-id');
var itemName = $(el).closest('.item').find('.item-name').text();
$('#notify__').modal('show');
$('#notify__ #notify_button').on('click', function(e) {
e.preventDefault();
var email = $('#notify__ .form-horizontal input').val();
var $container = $('.completed_message');
// this piece of code below is also from the docs /////////
BIS.create(email, variantId, productId).then(notificationCallback);
//something like this?? ///
$container.txt(msg);
});
}
How do I show the msg from notificationCallback everytime I click the submit button inside the modal?
In your notify modal dialog html markup put something like
<div id="#puttexthere"></div>
then you can do
$('#puttexthere').text(msg);
Hopefully what you need.

How to add content via ajax using the popover boostrap

I tried to view different sources and also looked into the forums posting similar question, but it didnt quite help me with the issue that im facing.
I have a text input filed to which I'm adding a popover to show similar a list of names in the database. The inout field checks for validation, to see if the name entered is unique, if not it displays similar names available in the database that could be re-used.
here is the popover snippet:
$("#account_name_create").popover({
title: 'Twitter Bootstrap Popover',
content: function (process) {
this.accountCollection = new ipiadmin.collections.AccountCollection();
var newName = $("#new-account-form #account_name_create").val();
var userFilter = "accountName~'" + newName + "'";
this.accountCollection.fetch({
data: { "f": userFilter,
"sortby": null,
"type":"ipi",
"pageno":0,
"pagesize":2,
"reversesort" : true
},
cache: false,
success: function(model, response, options) {
var states = [];
map = {};
$.each(model.aDataSet, function (i, state) {
map[state.accountName] = state;
states.push(state.accountName);
});
process(states); //gives an error saying 'undefined is not a function (says process is undefined)'
},
error: function(model, response, options) {
console.log('error');
}
});
},
});
here is the html:
<input type="text" id="account_name_create" name="account_name" class="" size="40" />
I'm not sure how why it says 'process' as undefined. Also not sure if this would be the correct way of displaying the data in the popover.
Any ideas??
Thanks!
process doesn't have scope in the success function, only in the content function. If you want to call the process function from within the success function, you could define it somewhere outside of the jQuery call.

Categories