How to reload jqGrid with 'setGridParam' key pair values? - javascript

I have tried to follow question in stackoverflow, but this doesn't help me in my case.
I have a checkbox on my web-page, which if gets clicked(true) shows, only negative values.
I am trying to send data from my JS file to Controllers with change parameters so the grid with negative values comes up.
But I am not getting any hit on controller while debugging it.
//Check for Negative Option
var negative;
$('#checkbox').click(function(){
{
var selected= $('#txtSelected').val();
var summary=$("#chkSummary").is(":checked");
var negative = $("#checkbox").is(":checked");
var locationIdList=$('#locationId').val()
ReloadGrid(selected, summary, negative, locationIdList);
}
})
Where StatusGridId is the name of my table.
function ReloadGrid(selected,summary,negative,locationId) {
$("#StatusGridId").jqGrid('clearGridData');
//Reload grid trigger
$("#StatusGridId").jqGrid('setGridParam',
{
url: "/Reports/GetStatus?"+"locationIdList="+locationId,
postData:{selected: selected, summary:summary, negative: negative}
}).trigger('reloadGrid');
}
My controller where I am not reciving any hit while debugging:
public JsonResult GetStatus ( string sidx, string sord, int? page, int? rows, string selected, string locationIdList, bool? summary, bool? negative )
{
-----code------
}

Related

how to get string 'Sugar&Jaggery, Salt' via <a> in codeigniter?

plz anyone me i m beginner in codeigniter in herf passing url with string but the whole can't get in
controller & can't accepting as sting so what shold i do for it plz someone help me
//Here is html code which pass sting value
index.php/Home/product_show?type='Sugar&Jaggery , Salt'">Sugar & Jaggery , Salt
//controller get sting in type variable but on Sugur got not whole sting and pass type variable to model
public function product_show(){
$type = $_GET['type'];
die(var_dump($type));
$data['testdata']= $this->Globle_model->get_multiple_record($type);
$this->load->view('display_product',$data);
}
//model type variable check the subcategory from database and return to controller
public function get_multiple_record($type){
$this->db->where_in('Subcategory_name',$type);
$get_data = $this->db->get('productmaster');
return $get_data->result_array();
}
//o/p
get this much of string(6) "'Sugar"
Please follow the below way to get all your string into the controller into
$_GET['type'] variable.
Combine all your strings into a single variable using _ into href
Example :
Sugar & Jaggery , Salt
In the controller, I have created one array() with variable subcategory_type .In which key is coming from the view but its value from the database.
Example :
function get_product_type(){
$get_info = $this->input->get();
$subcategory_type = array(
"Sugar_Jaggery_Salt" => "Sugar&Jaggery , Salt"
);
$type_arr = $subcategory_type[$get_info['type']];
$data['testdata']= $this->Globle_model->get_multiple_record($type_arr);
$this->load->view('display_product',$data);
}
In model,
function get_multiple_record($type_array){
$this->db->where_in('Subcategory_name',$type_array);
$get_data = $this->db->get('productmaster');
return $get_data->result_array();
}
Try this and update me in case of anything.

Prevent HTML read-only text fields to be changed

I'm developing a Grails web application whose modules, mostly, must implement a master-detail interface. As an approach, I want to put the following code to your consideration:
Master Class:
import org.codehaus.groovy.grails.web.json.JSONArray
class MyForm {
String name
String address
String detail
BigDecimal total
static hasMany = [details: MyFormDetail]
static constraints = {
name()
address()
detail()
total()
}
static mapping = {
detail type: 'text'
}
def beforeInsert = {
def detailJSON = new JSONArray(detail)
detailJSON.each {
def quantity = it.getAt("quantity").toString().toBigDecimal()
def description = it.getAt("description").toString()
def unitaryPrice = it.getAt("unitaryPrice").toString().toBigDecimal()
def subtotal = it.getAt("subtotal").toString().toBigDecimal()
def myFormDetail = new MyFormDetail(
quantity: quantity,
description: description,
unitaryPrice: unitaryPrice,
subtotal: subtotal
)
this.addToDetails(myFormDetail)
}
}
}
Detail Class:
class MyFormDetail {
Integer quantity
String description
BigDecimal unitaryPrice
BigDecimal subtotal
static belongsTo = [myForm: MyForm]
static constraints = {
quantity()
description()
unitaryPrice()
subtotal()
}
}
myFormUtilities.js helper file:
$(document).ready(function() {
$("#detailTable").jqGrid({
datatype: "local",
height: 100,
colNames: ["QUANTITY","DESCRIPTION","UNIT. PRICE","SUBTOTAL"],
colModel:[
{name:'quantity',index:'quantity', width:100},
{name:'description',index:'description', width:400},
{name:'unitaryPrice',index:'unitaryPrice', width:100},
{name:'subtotal',index:'subtotal', width:100}],
caption: "DETAIL"
});
createTable();
$("#addRow").bind("click",addRow);
$("#removeRow").bind("click",removeRow);
$("#quantity, #unitaryPrice").bind("keyup",calculateTotal);
function calculateTotal(){
let quantity = parseFloat($("#quantity").val());
let unitaryPrice = parseFloat($("#unitaryPrice").val());
let subtotal = quantity*unitaryPrice;
$("#subtotal").val(subtotal);
}
function addRow(){
let row = new Object();
row.quantity = $("#quantity").val();
row.description = $("#description").val();
row.unitaryPrice = $("#unitaryPrice").val();
row.subtotal = $("#subtotal").val();
let detailJSON = ($("#detail").val()=="")?"[]":$("#detail").val();
let mydata = $.parseJSON(detailJSON);
mydata.push(row);
$("#detail").val(JSON.stringify(mydata));
createTable();
}
function removeRow(){
let filaId = parseInt($('#detailTable').jqGrid('getGridParam','selrow')) - 1;
let mydata = $.parseJSON($("#detail").val());
let nuevoMydata = new Array();
for(let i=0;i<mydata.length;i++){
if(filaId!=i)
nuevoMydata.push(mydata[i]);
}
$("#detail").val(JSON.stringify(nuevoMydata));
createTable();
}
function createTable(){
let total = 0;
let aRow = new Object();
let detailJSON = ($("#detail").val()=="")?"[]":$("#detail").val();
let mydata = $.parseJSON(detailJSON);
$("#detailTable").jqGrid("clearGridData", true);
for(let i=0;i<mydata.length;i++){
aRow = mydata[i];
total += parseFloat(aRow.subtotal);
$("#detailTable").jqGrid('addRowData',i+1,aRow);
}
$("#total").val(total);
}
});
This is the displayed form (I know it's an autogenerated view but see it as a very basic GUI mockup, please):
So, these are the issues:
Both Subtotal and Total fields are calculated fields that were set
read-only to prevent user to modify their content, but I found that
using the browser element inspector their content and properties
(like read-only) can be modified.
Same happens with detail. If its content is altered, a server side
error will be produced when the instance is saved because the beforeInsert block needs a valid
JSON string to create the detail instances. This field is also used to generate the detail JqGrid. This field will be
hidden.
Everything with this example is working as expected but a fault could be caused by a curious user.
Is there a way to prevent these fields text to be changed even using
the inspector?
Is there another place to keep this data safe from alterations?
I'm using this detail field to save a JSON string and this is my solution to implement the master-detail pattern. Is there another
way to improve this implementation avoiding the need to define a
field for this string?
If your users have access to the inspector/web console, then they have access to all the client-side data that you do (they are only limited by their knowledge of how to use the browser's dev tools). They can change any element's text or input's value. Thus, the only place that would be 100% safe to store this data is on the server side.
What you can try, which would at least make it a lot more work for them to update anything, and might prevent the change events calling the server, is to hide each input (with CSS for instance) and replace it in the visible HTML with a <span> element (or some other non-form element). Then make sure that whenever the <input> value is changed, you update the text of the corresponding span. Something like:
$("#subtotalSpan").html( $("#subtotal").val() );
added inside the calculateTotal function. If you want them to not even be able to edit the HTML of a span, you could go even further and draw the value to a <canvas> instead of a <span>. They won't be able to change text drawn into a canvas element.
Sorry, there is no easy answer for protecting the data sent from the browser. Any user-submitted input should be treated as dirty by your server.
Data sent in a POST or GET can always be altered on the client side or even created wholesale (with something like CURL or Postman). For that reason, you should always validate the user input on the server side and compute your totals there.
If you have properties that you don't want to participate in the mass property data binding you should configure them with bindable: false.
You have this:
class MyFormDetail {
Integer quantity
String description
BigDecimal unitaryPrice
BigDecimal subtotal
static belongsTo = [myForm: MyForm]
static constraints = {
quantity()
description()
unitaryPrice()
subtotal()
}
}
You could change that to something like this:
class MyFormDetail {
Integer quantity
String description
BigDecimal unitaryPrice
BigDecimal subtotal
static belongsTo = [myForm: MyForm]
static constraints = {
quantity()
description()
unitaryPrice bindable: false
subtotal bindable: false
}
}
If you have something like this:
MyFormDetail mfd = new MyFormDetail()
// The body of the request will be read and
// bound to mfd but subtotal and unitaryPrice
// will NOT be updated...
mfd.properties = request
If you do that, you can still assign values those properties directly:
mfd.subtotal = // ... some value here
Another option is to submit your form to a controller action which accepts a command object. That CO could look like this...
class FormCommand {
Integer quantity
String description
}
If you have an action that looks like this:
class SomeController {
def someAction(FormCommand co) {
// it won't matter if subtotal
// and unitaryPrice are in the
// request, the co only has the
// the properties you want so now
// you can use those to update the
// corresponding persistent entity
// in a safe way
}
}

get sort direction from jquery bootgrid in C#

i have setup a jquery bootgrid on a .net mvc web page, it shows me a grid with a few commands,like sorting,search autocomplete,scroll pages. Library is here: http://www.jquery-bootgrid.com/documentation
The grid works well, and i decided to send the commands through ajax to a function behind. The library then sends a list of strings to the function, used to handle the grid:
current 1
rowCount 10
sort[filename] asc
where filename is one of the columns for which i wanna sort. it could be sort[id], sort[name] or whatever i set my column to be.
the values are pretty clear, the ajax sends to the function the current grid page,the number of rows and the sorting direction.
but when i get in the function i can read only the first 2 values:
public ActionResult AjaxRequestData(string current,string rowCount,string sort)
this definition reads the first 2 values from the web page,but cannot read the sort ,because the actual name of the var is sort[filename], it's not an array of strings.if i either declare sort as string or string[],the result is always null.
How should i declare the variables in the action? So far i could read the sort by using formcollection["sort[filename]"],formcollection["sort[id]"] etc but i have a lot of columns and i really dont want to write out a condition for each one of them,is there any other solution to this?
Approch1.
consider you have table with columns "col1, col2, col3, ...".
you can use:
public ActionResult AjaxRequestData(string current,string rowCount,Sort sort){
//sort.col1 == 'asc' (consider sorted by col1 in ascending order)
}
public class Sort
{
public string col1 { get; set; }
public string col2 { get; set; }
public string col3 { get; set; }
//... other columns
}
Approach 2.
You can remove you parameters and parse data manually. (notice i used post here instead of get)
[HttpPost]
public object AjaxRequestData(){
string jsonContent = Request.Content.ReadAsStringAsync().Result;
Dictionary<string, string> keyvalues = new Dictionary<string, string>();
string[] keyvalue_strings = jsonContent.Split('&');
string sort_column = "";
string sort_direction = "";
for (var i = 0; i< keyvalue_strings.Length; i++)
{
var a = keyvalue_strings[i].Split('=');
a[0] = a[0].Replace("%5B", "[").Replace("%5D", "]");
keyvalues.Add(a[0], (a[1]));
if (a[0].Contains("sort"))
{
sort_column = a[0].Replace("sort[", "").Replace("]", "");
sort_direction = a[1];
}
}
//now you have keyvalues, sort_column, sort_direction.
//...
}

Javascript Removing elements from an array based on another array

I am using javascript with knockout.js and I have 2 arrays:
self.timesheets = ko.observableArray();
self.selectedTimesheets = ko.observableArray();
I load the timesheet data like so:
$.ajax({
url: '/api/Invoice/GetPendingTimesheets',
type: 'GET',
success: function (timesheetData) {
self.timesheets(timesheetData);
}
});
Where the timesheets are defined like so:
public class Timesheet
{
public int Id { get; set; }
public DateTime WeekStart { get; set; }
}
The selectedTimesheets array keeps track of which checkboxes have been selected
What I would like to do is remove the elements in self.timesheets that are also in self.selectedtimesheets, and I am having a mental block figuring out how to do this:
I know there should be something like
self.timesheets.remove(function (el) {
// ????
});
But I just can't think of how to do it exactly.
Programmatically, you want to iterate through your self.timesheets array and compare each item's id to the ids in self.selectedtimesheets. If the ids match, you want to remove that item from self.timesheets.
Or push all items from both arrays into one new array and remove duplicates.
But since you're using Knockout, if you run the compareArrays utility function:
var differences = ko.utils.compareArrays(self.timesheets, self.selectedtimesheets);
differences will now be an array of only the different values.

Allow to use to add an item to model asp.net mvc4

The model:
public class oPage
{
public int PageId { get; set; }
public List<oContent> Contents { get; set; }
}
The oContent object have properties: Id and Text.
The view: (Razor)
#for (int i = 0; i <= Model.Agrees.Count; i++)
{
#Html.TextAreaFor(m => Model.Agrees[i].Text)
}
I want to let to user to add another content from the client.
I found some solutions that I don't like:
Write the html markup manually. I don't like it because maybe in one day the rendering's structure will change and my code will not word.
(Like here: http://www.techiesweb.net/asp-net-mvc3-dynamically-added-form-fields-model-binding/)
Get the structure from the server. I don't like this because.. well I'm always prefer not use the server unless I have to.
(Like here: How to add items to MVC model in javascript?)
I'm looking for a better and smarter solution.
The solution a little beat complex but I think that it cover all my points.
The logic is:
Get the html from the razor engine
#Html.TextAreaFor(m => Model.Agrees[i].Text).ToHtmlString()
Than replace the index number with the attributes name and id (It makes more sense than relying on all attribute value)
public static string CreateHelperTemplate(string PlaceholderPerfix, MvcHtmlString mvcHtmlString)
{
string Result = "";
XElement TempNode = XDocument.Parse(mvcHtmlString.ToHtmlString()).Root;
XAttribute AttrId = TempNode.Attribute("id");
AttrId.Value = AttrId.Value.Replace("0", PlaceholderPerfix);
XAttribute AttrName = TempNode.Attribute("name");
AttrName.Value = AttrName.Value.Replace("0", PlaceholderPerfix);
// Clear the content if exist
TempNode.SetValue(string.Empty);
Result = TempNode.ToString();
return Result;
}
The result it something like this:
<textarea class="form-control" cols="20" id="Perfix_$__Text" name="Agrees[$].Text" rows="2"></textarea>
Then, in javascript, when the user click on "Add item" button you can get the "template" and the index and replace the '$' with the index.
So, I not need to call the server and if the structure of the helper will change my code will still work.
It's working.

Categories

Resources