Let's say I have an entity User.
The User can have many Address.
In Address There's 2 fields :
Country
State
What I want :
When the user create his account, he can add as many address as he
wants.
When the user select a Country, it populate the State field based on the country.
What I've done :
UserType :
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('address', 'collection', array(
'type' => new AddressType(),
'allow_add' => true,
'allow_delete' => true))
//...
}
The Javascript to add address (which is working : based on symfony doc):
<script type="text/javascript">
$(document).ready(function() {
var $container = $('div#mybundle_user_address');
var $addLink = $('Add address');
$container.append($addLink);
$addLink.click(function(e) {
addAddress($container);
e.preventDefault();
return false;
});
var index = $container.find(':input').length;
$container.children('div').each(function() {
addDeleteLink($(this));
});
function addAddress($container) {
var $prototype = $($container.attr('data-prototype').replace(/__name__label__/g, 'Address n°' + (index+1))
.replace(/__name__/g, index));
addDeleteLink($prototype);
$container.append($prototype);
index++;
}
function addDeleteLink($prototype) {
$deleteLink = $('Delete');
$prototype.append($deleteLink);
$deleteLink.click(function(e) {
$prototype.remove();
e.preventDefault();
return false;
});
}
});
</script>
Ok, but now, How do I add I call a .change() on the select created after clicking on "add address" ?
Because if you add many address, divs will have this name :
#mybundle_user_address_0_country
#mybundle_user_address_1_country
#mybundle_user_address_2_country
...
So how do I select the div to have a .change() call of these divs ? And where do I put the javascript ? Inside the first javascript when I add divs ? Or outside ?
Related
I have a drop-down in j-table and I want to extract the selected value from it. Is there any way to get the selected option values from j-table.
sections_template_id: {
title: 'Template',
inputTitle: "Template*",
options: web_sections,
create: true,
edit: true,
list: true
}
, sec_hidden: {
type: 'hidden'
, inputTitle: "Template*"
, create: true
, edit: false
, list: false
, defaultValue: web_sections
}
i want to set the value of sections_template_id in sec_hidden
this is my route on which i am calling a function
Route::post('cms-web-section-templates',['as' => 'cms-web-section-templates', 'uses' => 'CmsController#Main_sections']);
and here is my function
public function Main_sections(Request $request)
{
$types = SectionType::getTypes();
$web_section = WebTemplate::all();
//dd($web_section);
$rows[] = array("DisplayText"=>"", "Value"=>"");
foreach ($web_section as $key => $web_sections) {
$rows[] = array(
'DisplayText' => $web_sections->name,
'Value' => $web_sections->id,
);
}
$this->response['Options'] = $rows;
$this->response['Result'] = "OK";
return json_encode($this->response);
}
I used jquery/javascript to grab data from jtable. I cant find in the jtable documentation how to grab the selected value. If you inspect element, once you select the row, a class is added in that row which is "jtable-row-selected".
<script>
var all_rows = [];
$('tr.jtable-row-selected').each(function(){
var len = $(this).children().length;
var row = [];
for(let i = 0;i < len; i+=1){
row.push($(this).children()[i].innerText)
}
all_rows.push(row);
})
//console.log(all_rows);
</script>
Try the jtable selectedRows method to get a jquery object of the selected rows.
The documentation https://jtable.org/ApiReference/Methods#met-selectedRows has short worked example how to get the record and fields for each selected row.
I still relatively new to ASP.Net and the concepts of communicating between client and server. I am using DevExpress tools but I believe this issue is more of a misunderstanding of the concept.
I have a GridView within a partial view that is loaded via an Action #Html.Action('MessageGridView'). This works no problem and data is loaded fine with the index and a returned model.
#Html.DevExpress().GridView(settings =>
{
settings.Width = System.Web.UI.WebControls.Unit.Percentage(100);
settings.Name = "preparedMessagesGrid";
settings.CallbackRouteValues = new { Controller = "Messages", Action = "MessagesGridView" };
settings.KeyFieldName = "Id";
settings.SettingsBehavior.AllowSelectByRowClick = true;
settings.SettingsBehavior.AllowSelectSingleRowOnly = true;
settings.ClientSideEvents.Init = "GridViewInit";
settings.ClientSideEvents.SelectionChanged = "OnSelectionChanged";
settings.ClientSideEvents.BeginCallback = "OnBeginCallback";
settings.SettingsBehavior.AllowEllipsisInText = true;
settings.PreRender = settings.Init = (sender, e) =>
{
MVCxGridView gridView = sender as MVCxGridView;
gridView.Selection.SelectAll();
};
settings.Columns.Add("Name");
settings.Columns.Add("Description");
}).Bind(Model.preparedMessages).GetHtml()
What I am trying to achieve is when the user selects the row I wish the data to be loaded into the popup control when clicked. Is there a way I can set the parameters dynamically for the popup control callback?
#Html.DevExpress().PopupControl(settings =>
{
settings.Name = "pcModalMode";
settings.Width = 100;
settings.AllowDragging = true;
settings.CloseAction = CloseAction.CloseButton;
settings.CloseOnEscape = true;
settings.PopupAnimationType = AnimationType.None;
settings.HeaderText = "Login";
settings.Modal = true;
settings.PopupHorizontalAlign = PopupHorizontalAlign.WindowCenter;
settings.PopupVerticalAlign = PopupVerticalAlign.WindowCenter;
settings.CallbackRouteValues = new { Controller = "Messages", Action = "Load", new { id = THIS NEEDS TO BE SELECTED ID VALUE} };
settings.LoadContentViaCallback = LoadContentViaCallback.OnFirstShow;
}).GetHtml()
It works if I set the value static so I'm one step away from getting this working. What I have researched is that I can get the values from the GridView in javascript using the selection changed event.
function OnSelectionChanged(s, e) {
s.GetSelectedFieldValues("Id", GetSelectedFieldValueCallback);
}
I can then retrieve this value but can I set this to my popup control or am I misunderstanding being relatively new and possibly I could do this server side for when the ViewGrid callback is performed, then set it server side with a session of some sort?
You're just one step away to get currently selected grid value with this function:
function OnSelectionChanged(s, e) {
s.GetSelectedFieldValues('Id', GetSelectedFieldValueCallback);
}
What you need to do is declaring GetSelectedFieldValueCallback method as this (I got from a test that selectedValue contains array with single value for single grid row selection, use zero index to assign the value):
var id; // a global variable set to hold selected row key value from grid
function GetSelectedFieldValueCallback(selectedValue) {
if (selectedValue.length == 0)
return;
id = parseInt(selectedValue[0]);
pcModalMode.PerformCallback();
}
Then setting BeginCallback on PopupControl helper as given below, note that for DevExpress HTML helpers you can use customArgs in client-side to pass action method parameters instead of using CallbackRouteValues with id parameter:
#Html.DevExpress().PopupControl(settings =>
{
settings.Name = "pcModalMode";
// other stuff
settings.CallbackRouteValues = new { Controller = "Messages", Action = "Load" };
settings.ClientSideEvents.BeginCallback = "OnPopUpBeginCallback";
settings.ClientSideEvents.EndCallback = "OnPopUpEndCallback";
// other stuff
}).GetHtml()
// JS function for popup callback
function OnPopUpBeginCallback(s, e) {
e.customArgs["id"] = id; // this sends 'id' as action method parameter to `Load` action
}
// Optional end callback
function OnPopUpEndCallback(s, e) {
if (!pcModalMode.IsVisible())
pcModalMode.Show();
}
Finally, let's putting them all together in view & controller code:
View
<!-- View page -->
<script type="text/javascript">
var id;
function OnSelectionChanged(s, e) {
s.GetSelectedFieldValues('Id', GetSelectedFieldValueCallback);
}
function GetSelectedFieldValueCallback(selectedValue) {
if (selectedValue.length == 0)
return;
id = parseInt(selectedValue[0]);
pcModalMode.PerformCallback();
}
function OnPopUpBeginCallback(s, e) {
e.customArgs["id"] = id;
}
function OnPopUpEndCallback(s, e) {
if (!pcModalMode.IsVisible())
pcModalMode.Show();
}
</script>
GridView (partial view)
#Html.DevExpress().GridView(settings =>
{
settings.Name = "preparedMessagesGrid";
// other stuff
settings.ClientSideEvents.SelectionChanged = "OnSelectionChanged";
}).Bind(Model.preparedMessages).GetHtml()
Popup (partial view)
#Html.DevExpress().PopupControl(settings =>
{
settings.Name = "pcModalMode";
// other stuff
settings.CallbackRouteValues = new { Controller = "Messages", Action = "Load" };
settings.ClientSideEvents.BeginCallback = "OnPopUpBeginCallback";
settings.ClientSideEvents.EndCallback = "OnPopUpEndCallback";
// other stuff
}).GetHtml()
Controller
public class Messages : Controller
{
public ActionResult MessagesGridView()
{
// grid view populating data code lines here
return PartialView("_GridView", data);
}
public ActionResult Load(int id)
{
// code lines to find ID here
return PartialView("_ModalPopup", model);
}
}
References:
(1) Display GridView Row Details in PopupControl Window
(2) How to display detail data within a popup window (MVC)
(3) ASPxClientGridView.GetSelectedFieldValues (DevExpress Documentation)
(4) MVCxClientBeginCallbackEventArgs.customArgs (DevExpress Documentation)
I have the following fields on my form / web page with some fields that I would like to be calculated when a user types. (see image)
Fields - image here
The field Unit Cost is calculated by Case Cost / Case Size. I have that functioning perfectly with the following code
Casesize Textbox
#Html.TextBoxFor(model => model.q_supplierproduct.q_casesize, "{0:#.#}", new { #class = "calc" })
Case Cost Textbox
#Html.TextBoxFor(model => model.q_supplierproduct.q_casecost, "{0:#.#}", new { #class="calc"})
Unit Cost Textbox
#Html.TextBoxFor(model=> model.q_unitcost, "{0:#.#}", new { #class = "calc" })
Function
#* Calculate Unitcost value *#
<script>
var url = '#Url.Action("CalculateUnitCost", "CalculateValues")';
$('.calc').change(function () {
//get the values of the texboxes
var casecost = $('#q_supplierproduct_q_casecost').val();
var casesize = $('#q_supplierproduct_q_casesize').val();
//check if field entries are valid
if (casecost == '' || casesize == '' || isNaN(casecost) || isNaN(casesize)) { return; }
$.post(url, { Q_casecost: casecost, Q_casesize: casesize }, function (response) {
$('#q_unitcost').val(response);
});
});
</script>
Controller
public class CalculateValuesController : Controller
{
[HttpPost]
public JsonResult CalculateUnitCost(double Q_casecost, double Q_casesize)
{
var result = Computation.GetUnitCost(Q_casecost, Q_casesize);
return Json(result.ToString("#.#"));
}
Method
public class Computation
{
public static double GetUnitCost(double Q_casecost, double Q_casesize)
{
double unitcostresult = Q_casecost / Q_casesize;
return unitcostresult;
}
Just to mention again, this code works as expected, when I change the values in casesiez and casecost, the unitcost field updates accordingly. The next thing I wanted to achieve was to calculate the profit field based on a values entered in the price field minus unit cost field (which is a previously calculated field). I went on to add a second script for that field plus the respective calculations in the controller and method
See two scripts image
<script>
var url = '#Url.Action("CalculateProfit", "CalculateValues")';
$('.calc').change(function () {
//get the values of the texboxes
var sellprice = $('#q_sellprice').val();
var unitcost = $('#q_unitcost').val();
//check if field entries are valid
if (sellprice == '' || unitcost == '' || isNaN(sellprice) || isNaN(unitcost)) { return; }
$.post(url, { Q_sellprice: sellprice, Q_unitcost: unitcost }, function (response) {
$('#q_profit').val(response);
});
});
from this point onwards with this addition, unit cost field stops working (no update when data is entered), but profit field will calculate accordingly if I type values in unit cost and price field. (new scripts stops the first one from working as intended). What am I missing here?
Is it because of the common unit cost field in both scripts that causing the issue? How do I fix?
After reading the comments from Stephen and Tetsuya I changed the code to the following, and that solved my problem. The two fields unitcost and profit are updating now based on the respective changed fields. I do not call any action method here and I am doing all calculations in javascript as advised.
<script>
function calculate()
{
//Fields that are used for calculations
var casecost = parseFloat($('#q_supplierproduct_q_casecost').val());
var casesize = parseFloat($('#q_supplierproduct_q_casesize').val());
var price = parseFloat($('#q_sellprice').val());
//Calculations
var unitcost = casecost / casesize; // get unitcost from casecost FIELD and casesize FIELD
var profit = price - unitcost; // get profit from price FIELD and unicost CALCULATED value
//set results to the updating fields
$('#q_unitcost').val(unitcost.toFixed(2));
$('#q_profit').val(profit.toFixed(2));
}
$(document).ready(function () {
//calculate();
//calculate everytime these following fields change
$('#q_supplierproduct_q_casecost').change(calculate);
$('#q_supplierproduct_q_casesize').change(calculate);
$('#q_sellprice').change(calculate);
$(unitcost).change(calculate);
});
</script>
Hope this helps someone else down the road.
I´m supporting API where I need to update validation into javascript method:
function AddCategory() {
var category = $("#category");
var subCategory = $("#subcategory");
if (category.val().length > 0 && subCategory.val().length > 0) {
var grid = $("#lstCategory").data("kendoGrid");
var listGrid = $("#lstCategory").data().kendoGrid.dataSource.data();
var dataS = grid.dataSource;
if (!FindObjectInList(listGrid, "idSubcategory", subCategory.val())) {
dataS.add({
idCategory: category.val(),
category: $("option:selected", category).text(),
idSubcategory: subCategory.val(),
subCategory: $("option:selected", subCategory).text()
});
dataS.sync();
}
else {
InfoMessage("Category", "Selected subcategory cannot add again");
}
} else {
WarningMessage("Warning", "Select category and subcategory...");
}
}
I need to remove this validation:
InfoMessage("Category", "Selected subcategory cannot add again");
But I don´t understand how this method works, anyone can explain me it? Regards
How it works:
First, pass listGrid, idSubcategory and the value returned from subCategory.val() into FindObjectInList. If null is returned (the category does not exist) - then add the new category information passed in. Else, if the function returns true (the category already exists) then serve up the notification to the user via the InfoMessage function.
if (!FindObjectInList(listGrid, "idSubcategory", subCategory.val())) {
dataS.add({
idCategory: category.val(),
category: $("option:selected", category).text(),
idSubcategory: subCategory.val(),
subCategory: $("option:selected", subCategory).text()
});
dataS.sync();
}
else {
InfoMessage("Category", "Selected subcategory cannot add again");
I am trying to populate a sublist in a suitelet with data from a custom saved search that I have already created. My problem is that the sublist is only populating data from fields that correspond to the "type" of saved search I am doing. For example, in this instance the saved search is a "transaction" type search. If, for example, I want to reference a customer field withing the saved search, say "Name" and "Billing Address", this data will not populate the sublist in the suitelet. All other fields that are being referenced in the Transaction record itself populate the sublist fine. I was just wondering if anyone has ever run into the same issue, anyways here's the code I'm trying to implement.
var form,
sublist;
//GET
if (request.getMethod() == 'GET')
{
//create form
form = nlapiCreateForm('Test Custom Suitelet Form', false);
//create sublist to show results
sublist = form.addSubList('custpage_sublist_id', 'list', 'Item List');
//form buttons
form.addSubmitButton('Submit');
form.addResetButton('Reset');
// run existing saved search
var searchResults = nlapiSearchRecord('transaction','customsearchID');
var columns = searchResults[0].getAllColumns();
// Add the search column names to the sublist field
for ( var i=0; i< columns.length; i++ )
{
sublist.addField(columns[i].getName() ,'text', columns[i].getLabel() );
nlapiLogExecution('DEBUG', 'Column Label',columns[i].getLabel());
}
//additional sublist fields
sublist.addMarkAllButtons();
sublist.addField('custfield_selected', 'checkbox', 'Selected');
sublist.setLineItemValues(searchResults)
response.writePage(form);
}
If you review the nlobjSublist docs you'll see that sublist.setLineItemValues can also take an array of hashes. What does work is:
function getJoinedName(col) {
var join = col.getJoin();
return join ? col.getName() + '__' + join : col.getName();
}
searchResults[0].getAllColumns().forEach(function(col) {
sublist.addField(getJoinedName(col), 'text', col.getLabel());
nlapiLogExecution('DEBUG', 'Column Label', col.getLabel());
});
var resolvedJoins = searchResults.map(function(sr) {
var ret = {
id: sr.getId()
};
sr.getAllColumns().forEach(function(col) {
ret[getJoinedName(col)] = sr.getText(col) || sr.getValue(col);
});
return ret;
});
sublist.setLineItemValues(resolvedJoins);